Com o Cloud Functions (2ª geração), é possível acionar funções em resposta a eventos personalizados. Esses eventos são fornecidos por provedores de eventos especiais ou adicionais, em vez de serem eventos do Firebase com suporte nativo do SDK do Firebase para Cloud Functions. Ao usar acionadores de eventos personalizados, o app pode responder a eventos fornecidos pelo Firebase Extensions. No entanto, também é possível publicar eventos personalizados próprios 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. São aplicadas as taxas de uso do Eventarc.
Acionar funções com eventos personalizados
É possível publicar eventos personalizados (ou receber eventos das extensões do Firebase) e acionar funções em resposta a esses eventos, implementando este fluxo básico:
- Publique os eventos desejados em um canal do Eventarc ou identifique os eventos disponíveis fornecidos por uma extensão que você instalou.
- No código da função, inscreva-se em eventos no canal do Eventarc com um manipulador de eventos.
- Na função, analise o payload retornado no objeto do CloudEvent e execute a lógica personalizada que seu app exigir.
Por exemplo, um app de jogo pode enviar notificações aos usuários quando eles entram ou saem do ranking dos dez principais jogadores. Esse app pode publicar eventos do ranking no canal padrão e processar esses dados em uma função que envia notificações push direcionadas aos usuários.
Um outro exemplo seria uma extensão projetada para ajudar apps a processar imagens grandes e que emite um evento quando o redimensionamento do arquivo é concluído. Os apps com essa extensão instalada podem processar o evento de conclusão atualizando os links no app 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. Para publicar eventos fora do Cloud Functions for Firebase,
adicione explicitamente o campo source
ao payload do evento.
Processar eventos personalizados
É possível processar todos os eventos personalizados, incluindo os de extensões, com os gerenciadores onCustomEventPublished
ou on_custom_event_published
. Primeiro, importe esse gerenciador do SDK do Eventarc com o
Firebase Admin SDK:
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");
Python
from firebase_admin import firestore, initialize_app
from firebase_functions import eventarc_fn
No código da função, transmita 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
});
Python
@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, o payload retornado no objeto de evento fornece dados que podem ser usados para executar a lógica personalizada do 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, acessando o nome de arquivo em
subject
e salvando os metadados de data
fornecidos
pelo evento.
Publicar e processar eventos em canais não padrão
Os canais personalizados são úteis para quando você tem necessidades especiais de permissão, ou outros requisitos, e não quer o mesmo nível de visibilidade e acesso para todos os eventos. É possível criar seus próprios canais usando o console do Google Cloud. A publicação e inscrição nos eventos precisam ser feitas no mesmo canal.
Quando um evento personalizado é publicado em um canal não padrão,
é necessário especificar o canal no código da função. Por exemplo, se você
quiser processar eventos publicados em um canal não padrão para o
local us-west1
, especifique 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) => { ... });
Python
@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)
# ...