Creare e gestire gli attivatori di eventi personalizzati

Con Cloud Functions (2ª gen.), puoi attivare le funzioni in risposta a eventi personalizzati. Si tratta di eventi forniti da fornitori di eventi speciali o aggiuntivi, diversamente dagli eventi Firebase supportati nativamente dall'SDK Firebase per Cloud Functions. Tramite gli attivatori di eventi personalizzati, la tua app può rispondere agli eventi forniti daFirebase Extensions oppure puoi pubblicare i tuoi eventi personalizzati e attivare funzioni in risposta.

Tutti gli eventi personalizzati sono conformi al formato evento JSON CloudEvents e vengono pubblicati in Eventarc. Si applicano Eventarc tariffe di utilizzo.

Attivare funzioni con eventi personalizzati

Puoi pubblicare eventi personalizzati (o ottenere eventi dalle estensioni Firebase) e attivare funzioni in risposta a questi eventi implementando questo flusso di base:

  1. Pubblica gli eventi desiderati in un canale Eventarc o identifica gli eventi disponibili forniti da un'estensione che hai installato.
  2. Nel codice della funzione, iscriviti agli eventi sul canale Eventarc con un gestore di eventi.
  3. Nella funzione, analizza il payload restituito nell'oggetto CloudEvent ed esegui la logica personalizzata richiesta dalla tua app.

Ad esempio, un'app di giochi potrebbe voler inviare notifiche agli utenti quando entrano o escono dalla classifica dei primi dieci concorrenti. Questa app potrebbe pubblicare gli eventi della classifica nel canale predefinito e poi gestire l'evento in una funzione che invia notifiche push mirate agli utenti.

In un altro esempio, un'estensione progettata per aiutare le app a elaborare immagini di grandi dimensioni potrebbe emettere un evento al termine del ridimensionamento delle immagini. Le app con questa estensione installata potrebbero gestire l'evento di completamento aggiornando i link nell'app in modo che rimandino alle versioni ridimensionate dell'immagine.

Pubblicare un evento in un canale

Gli eventi Eventarc vengono pubblicati nei canali. I canali sono un modo per raggruppare eventi correlati e gestire le autorizzazioni di accesso. Quando installi un'estensione o esegui il deployment di una funzione che utilizza eventi personalizzati, Firebase crea automaticamente un canale predefinito denominato firebase nella regione us-central1. Firebase Admin SDK fornisce un sottopacchetto eventarc per la pubblicazione sui canali.

Per pubblicare un evento da un server attendibile (o da un'altra funzione) utilizzando il canale predefinito:

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 . . .'
    }
});

Oltre a creare automaticamente il canale predefinito, Firebase imposta la variabile di ambiente EVENTARC_CLOUD_EVENT_SOURCE, che specifica l'origine dell'evento. Se pubblichi eventi al di fuori di Cloud Functions for Firebase, dovrai aggiungere esplicitamente il campo source nel payload dell'evento.

Gestire gli eventi personalizzati

Puoi gestire tutti gli eventi personalizzati, inclusi gli eventi delle estensioni, con gli gestori onCustomEventPublished o on_custom_event_published. Innanzitutto, importa questo gestore dall'SDK Eventarc insieme a 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

Nel codice della funzione, passa il nome dell'evento come mostrato per la funzione di esempio:

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

Per ogni estensione specifica, il payload restituito nell'oggetto evento fornisce dati che puoi utilizzare per eseguire la logica personalizzata per il flusso dell'applicazione. In questo caso, la funzione utilizza Admin SDK per copiare i metadati relativi all'immagine di cui è stato modificato il formato in una raccolta in Cloud Firestore, ottenendo il nome file da subject fornito dall'evento e salvando i metadati da data fornito dall'evento.

Pubblicare e gestire eventi su canali non predefiniti

I canali personalizzati possono essere utili nei casi in cui hai bisogno di autorizzazioni speciali o di altri requisiti e non vuoi lo stesso livello di visibilità e accesso per tutti gli eventi. Puoi creare i tuoi canali utilizzando la console Google Cloud. La pubblicazione e l'iscrizione agli eventi devono essere eseguite sullo stesso canale.

Se un evento personalizzato viene pubblicato su un canale diverso da quello predefinito, devi specificare il canale nel codice della funzione. Ad esempio, se vuoi gestire gli eventi pubblicati in un canale non predefinito per la località us-west1, devi specificare il canale come mostrato di seguito:

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)
    # ...