Criar e gerenciar gatilhos de eventos personalizados

Com o Cloud Functions (2ª geração), você pode acionar funções em resposta a eventos personalizados . Esses são eventos fornecidos por provedores de eventos especiais ou adicionais, em oposição aos eventos do Firebase com suporte nativo do SDK do Firebase para Cloud Functions. Por meio de acionadores de eventos personalizados, seu aplicativo pode responder a eventos fornecidos pelas extensões do Firebase ou você pode publicar seus próprios eventos personalizados e acionar funções em resposta a eles.

Todos os eventos personalizados estão em conformidade com o formato de evento JSON do CloudEvents e são publicados no Eventarc . Aplicam-se taxas de uso do Eventarc.

Funções de gatilho com eventos personalizados

Você pode publicar eventos personalizados (ou obter eventos de extensões do Firebase) e acionar funções em resposta a esses eventos implementando este fluxo básico:

  1. Publique os eventos desejados em um canal do Eventarc ou identifique os eventos disponíveis fornecidos por uma extensão que você instalou.
  2. No seu código de função, inscreva-se em eventos no canal Eventarc com um manipulador de eventos.
  3. Na função, analise a carga retornada no objeto CloudEvent e execute qualquer lógica personalizada que seu aplicativo exigir.

Por exemplo, um aplicativo de jogo pode querer enviar notificações aos usuários quando eles entram ou saem da tabela de classificação dos dez principais concorrentes. Este aplicativo pode publicar eventos de tabela de classificação no canal padrão e, em seguida, manipular o evento em uma função que envia notificações push direcionadas aos usuários.

Em outro exemplo, uma extensão projetada para ajudar os aplicativos a processar imagens grandes pode emitir um evento na conclusão do redimensionamento da imagem. Os aplicativos com esta extensão instalada podem lidar com o evento de conclusão atualizando links no aplicativo para apontar para versões redimensionadas da imagem.

Publicar um evento em um canal

Os eventos do Eventarc são publicados em canais . Os canais são uma forma de agrupar eventos relacionados e gerenciar permissões de acesso. Quando você instala uma extensão ou implanta uma função que consome eventos personalizados, o Firebase cria automaticamente um canal padrão chamado firebase na região us-central1 . O Firebase Admin SDK fornece um subpacote eventarc para publicação em canais.

Para publicar um evento de um servidor confiável (ou outra função) usando o canal padrão:

import {getEventarc} from 'firebase-admin/eventarc';

getEventarc().channel().publish({
    type: 'achieved-leaderboard',
    subject: 'Welcome to the top 10',
    data: {
      message: 'You have achieved the nth position in our leaderboard!  To see . . .'
    }
});

Além de criar automaticamente o canal padrão, o Firebase define a variável de ambiente EVENTARC_CLOUD_EVENT_SOURCE , que especifica a origem do evento. Se você estiver publicando eventos fora do Cloud Functions para Firebase, precisará adicionar explicitamente o campo source na carga do evento.

Lidar com eventos personalizados

Você pode lidar com todos os eventos personalizados, incluindo eventos de extensões, com os manipuladores onCustomEventPublished ou on_custom_event_published . Primeiro, importe este manipulador do SDK do Eventarc junto com o SDK Admin do Firebase:

Node.js

const {onCustomEventPublished} = require("firebase-functions/v2/eventarc");
const logger = require("firebase-functions/logger");
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

Pitão

from firebase_admin import firestore, initialize_app
from firebase_functions import eventarc_fn

No código da função, passe o nome do evento conforme mostrado na função de exemplo:

Node.js

exports.onimageresized = onCustomEventPublished(
    "firebase.extensions.storage-resize-images.v1.complete",
    (event) => {
      logger.info("Received image resize completed event", event);
      // For example, write resized image details into Firestore.
      return getFirestore()
          .collection("images")
          .doc(event.subject.replace("/", "_")) // original file path
          .set(event.data); // resized images paths and sizes
    });

Pitão

@eventarc_fn.on_custom_event_published(
    event_type="firebase.extensions.storage-resize-images.v1.complete")
def onimageresized(event: eventarc_fn.CloudEvent) -> None:
    print("Received image resize completed event: ", event.type)

    if not isinstance(event.subject, str):
        print("No 'subject' data.")
        return

    # For example, write resized image details into Firestore.
    firestore_client: google.cloud.firestore.Client = firestore.client()
    collection = firestore_client.collection("images")
    doc = collection.document(event.subject.replace("/", "_"))  # original file path
    doc.set(event.data)  # resized images paths and sizes

Para cada extensão específica, a carga retornada no objeto de evento fornece dados que você pode usar para executar uma lógica personalizada para o fluxo do seu aplicativo. Nesse caso, a função usa o Admin SDK para copiar metadados sobre a imagem redimensionada para uma coleção no Cloud Firestore, obtendo o nome do arquivo do subject fornecido pelo evento e salvando os metadados dos data fornecidos pelo evento.

Publicar e gerenciar eventos em canais não padrão

Os canais personalizados podem ser úteis para casos em que você tem necessidades de permissão especial ou outros requisitos e não deseja o mesmo nível de visibilidade e acesso para todos os eventos. Você pode criar seus próprios canais usando o console do Google Cloud . A publicação e inscrição em eventos devem ser feitas no mesmo canal.

Nos casos em que um evento personalizado é publicado em um canal não padrão, você precisará especificar o canal no seu código de função. Por exemplo, se quiser lidar com eventos publicados em um canal não padrão para o local us-west1 , será necessário especificar o canal conforme mostrado:

Node.js

import { onCustomEventPublished } from "firebase-functions/v2/eventarc";

export const func = onCustomEventPublished(
    {
      eventType: "firebase.extensions.storage-resize-images.v1.complete",
      channel: "locations/us-west1/channels/firebase",
      region: "us-west1",
    },
    (event) => { ... });

Pitão

@eventarc_fn.on_custom_event_published(
    event_type="firebase.extensions.storage-resize-images.v1.complete",
    channel="locations/us-west1/channels/firebase",
    region="us-west1")
def onimageresizedwest(event: eventarc_fn.CloudEvent) -> None:
    print("Received image resize completed event: ", event.type)
    # ...