Gatilhos do Firebase Authentication

O Cloud Run functions pode ser acionado por eventos do Firebase Authentication no mesmo projeto do Google Cloud que a função. Entre esses eventos estão a criação e a exclusão de usuários. Por exemplo, é possível enviar um e-mail de boas-vindas para um usuário que acabou de criar uma conta no app.

Tipos de evento

O Firebase Authentication pode acionar funções em resposta a eventos create e delete do usuário.

Tipo de evento Gatilho
providers/firebase.auth/eventTypes/user.create Acionado quando uma conta de usuário é criada.
providers/firebase.auth/eventTypes/user.delete Acionado quando uma conta de usuário é excluída.

Criação de usuário

As contas do Firebase acionam eventos de criação de usuários do Cloud Run functions quando:

  • um usuário criar uma conta de e-mail e uma senha;

  • um usuário fizer login pela primeira vez com um provedor de identidade federado;

  • o desenvolvedor criar uma conta com o SDK Admin do Firebase;

  • um usuário fizer login em uma sessão de autenticação anônima pela primeira vez.

Exclusão de usuário

Também é possível configurar uma função para acionamento mediante exclusão do usuário.

Estrutura do evento

Os dados do evento são fornecidos como um objeto UserRecord.

Um exemplo de evento de criação de conta baseada em senha é mostrado abaixo:

{
  "email": "me@example.com",
  "metadata": {
      "createdAt": "2018-10-19T19:29:16Z"
  },
  "uid": "XXXXX"
}

Algumas propriedades desse objeto são definidas somente ao usar determinados métodos de autenticação. Por exemplo, os eventos de conta baseada em senha definem uma propriedade email que contém o endereço de e-mail do usuário. A propriedade uid (que contém um ID do usuário exclusivo para seu projeto) é sempre definida.

Exemplo de código

Node.js

/**
 * Background Function triggered by a change to a Firebase Auth user object.
 *
 * @param {!Object} event The Cloud Functions event.
 */
exports.helloAuth = event => {
  try {
    console.log(`Function triggered by change to user: ${event.uid}`);
    console.log(`Created at: ${event.metadata.createdAt}`);

    if (event.email) {
      console.log(`Email: ${event.email}`);
    }
  } catch (err) {
    console.error(err);
  }
};

Python

import json

def hello_auth(data, context):
    """Triggered by creation or deletion of a Firebase Auth user object.
    Args:
           data (dict): The event payload.
           context (google.cloud.functions.Context): Metadata for the event.
    """
    print("Function triggered by creation/deletion of user: %s" % data["uid"])
    print("Created at: %s" % data["metadata"]["createdAt"])

    if "email" in data:
        print("Email: %s" % data["email"])

Go


// Package firebase contains a Firestore Cloud Function.
package firebase

import (
	"context"
	"log"
	"time"
)

// AuthEvent is the payload of a Firestore Auth event.
type AuthEvent struct {
	Email    string `json:"email"`
	Metadata struct {
		CreatedAt time.Time `json:"createdAt"`
	} `json:"metadata"`
	UID string `json:"uid"`
}

// HelloAuth is triggered by Firestore Auth events.
func HelloAuth(ctx context.Context, e AuthEvent) error {
	log.Printf("Function triggered by creation or deletion of user: %q", e.UID)
	log.Printf("Created at: %v", e.Metadata.CreatedAt)
	if e.Email != "" {
		log.Printf("Email: %q", e.Email)
	}
	return nil
}

Java

import com.google.cloud.functions.Context;
import com.google.cloud.functions.RawBackgroundFunction;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.util.logging.Logger;

public class FirebaseAuth implements RawBackgroundFunction {
  private static final Logger logger = Logger.getLogger(FirebaseAuth.class.getName());

  // Use GSON (https://github.com/google/gson) to parse JSON content.
  private static final Gson gson = new Gson();

  @Override
  public void accept(String json, Context context) {
    JsonObject body = gson.fromJson(json, JsonObject.class);

    if (body != null && body.has("uid")) {
      logger.info("Function triggered by change to user: " + body.get("uid").getAsString());
    }

    if (body != null && body.has("metadata")) {
      JsonObject metadata = body.get("metadata").getAsJsonObject();
      logger.info("Created at: " + metadata.get("createdAt").getAsString());
    }

    if (body != null && body.has("email")) {
      logger.info("Email: " + body.get("email").getAsString());
    }
  }
}

C#

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Firebase.Auth.V1;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;

namespace FirebaseAuth;

public class Function : ICloudEventFunction<AuthEventData>
{
    private readonly ILogger _logger;

    public Function(ILogger<Function> logger) =>
        _logger = logger;

    public Task HandleAsync(CloudEvent cloudEvent, AuthEventData data, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Function triggered by change to user: {uid}", data.Uid);
        if (data.Metadata is UserMetadata metadata)
        {
            _logger.LogInformation("User created at: {created:s}", metadata.CreateTime.ToDateTimeOffset());
        }
        if (!string.IsNullOrEmpty(data.Email))
        {
            _logger.LogInformation("Email: {email}", data.Email);
        }

        // In this example, we don't need to perform any asynchronous operations, so the
        // method doesn't need to be declared async.
        return Task.CompletedTask;
    }
}

Ruby

require "functions_framework"

# Triggered by creation or deletion of a Firebase Auth user object.
FunctionsFramework.cloud_event "hello_auth" do |event|
  # Event-triggered Ruby functions receive a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  # The Firebase event payload can be obtained from the `data` field.
  payload = event.data

  logger.info "Function triggered by creation/deletion of user: #{payload['uid']}"
  logger.info "Created at: #{payload['metadata']['createdAt']}"
  logger.info "Email: #{payload['email']}" if payload.key? "email"
end

PHP


use Google\CloudFunctions\CloudEvent;

function firebaseAuth(CloudEvent $cloudevent)
{
    $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb');
    $data = $cloudevent->getData();

    fwrite(
        $log,
        'Function triggered by change to user: ' . $data['uid'] . PHP_EOL
    );
    fwrite($log, 'Created at: ' . $data['metadata']['createTime'] . PHP_EOL);

    if (isset($data['email'])) {
        fwrite($log, 'Email: ' . $data['email'] . PHP_EOL);
    }
}

Como implantar a função

Para implantar a função, você precisa especificar o tipo de evento e o projeto em que o Firebase Auth está configurado. No console do Google Cloud, há um único campo para Tipo de evento, já que o projeto é considerado igual ao projeto que contém a função.

Porém, na linha de comando, você precisa usar strings específicas para determinar esses dois parâmetros. O comando gcloud a seguir implanta uma função que é acionada pelos eventos create do usuário:

gcloud functions deploy FUNCTION_NAME \
  --no-gen2 \
  --entry-point ENTRY_POINT \
  --trigger-event providers/firebase.auth/eventTypes/user.create \
  --trigger-resource YOUR_PROJECT_ID \
  --runtime RUNTIME
Argumento Descrição
FUNCTION_NAME O nome registrado do Cloud Run functions que você está implantando. Pode ser o nome de uma função no código-fonte ou uma string arbitrária. Se FUNCTION_NAME for uma string arbitrária, você precisará incluir a sinalização --entry-point.
--entry-point ENTRY_POINT O nome de uma função ou classe no código-fonte. Opcional, a menos que você não tenha usado FUNCTION_NAME para especificar a função no código-fonte a ser executada durante a implantação. Nesse caso, use --entry-point para fornecer o nome da função executável.
--trigger-event NAME O nome do tipo de evento que aciona a função. Neste caso, ele precisa ser um dos de criação ou exclusão, conforme listado acima.
--trigger-resource NAME O ID (neste exemplo, YOUR_PROJECT_ID) do projeto que contém sua função e o Firebase Authentication.
--runtime RUNTIME O nome do ambiente de execução que você está usando. Para uma lista completa, consulte a referência do gcloud.