Estendi Datastore con Cloud Functions (2nd gen)

Con le funzioni Cloud Run e Eventarc, puoi eseguire il deployment del codice gestire gli eventi attivati da modifiche nel database Firestore in modalità Datastore. In questo modo, puoi aggiungere funzionalità lato server senza dover eseguire i tuoi server.

Trigger in modalità Datastore

Eventarc supporta il seguente evento Firestore in modalità Datastore che ti consentono di creare gestori di funzioni Cloud Run (2ª generazione.) collegati Eventi di Firestore in modalità Datastore:

Tipo di evento Trigger
google.cloud.datastore.entity.v1.created Si attiva quando un'entità viene scritta per la prima volta.
google.cloud.datastore.entity.v1.updated Viene attivato quando esiste già un'entità e viene modificato un valore.
google.cloud.datastore.entity.v1.deleted Attivato quando viene eliminata un'entità.
google.cloud.datastore.entity.v1.written Si attiva quando viene attivato created, updated o deleted.
google.cloud.datastore.entity.v1.created.withAuthContext Uguale a created, ma con l'aggiunta delle informazioni di autenticazione.
google.cloud.datastore.entity.v1.updated.withAuthContext Uguale a updated, ma con l'aggiunta delle informazioni di autenticazione.
google.cloud.datastore.entity.v1.deleted.withAuthContext Uguale a deleted, ma con l'aggiunta delle informazioni di autenticazione.
google.cloud.datastore.entity.v1.written.withAuthContext Come written, ma aggiunge le informazioni di autenticazione.

Gli attivatori di eventi in modalità Datastore rispondono solo alle modifiche delle entità. Un aggiornamento a un'entità in modalità Datastore in cui i dati rimangono invariati (una scrittura senza operazioni) non genera un evento di aggiornamento o scrittura. Non puoi generare eventi solo per proprietà specifiche.

Includi il contesto di autenticazione nell'evento

Per includere informazioni di autenticazione aggiuntive sull'evento, utilizza un evento con l'estensione withAuthContext. Questa estensione aggiunge ulteriori informazioni sull'entità che ha attivato l'evento. Aggiunge gli attributi authtype e authid oltre alle informazioni restituite nell'evento di base. Per ulteriori informazioni sui valori degli attributi, consulta la documentazione di riferimento di authcontext.

Scrivere una funzione attivata da entità

Per scrivere una funzione che risponda a Firestore in eventi in modalità Datastore, preparati a specificare quanto segue durante il deployment:

  • un tipo di evento trigger
  • un filtro di eventi di trigger per selezionare le entità associate alla funzione
  • il codice della funzione da eseguire

Filtri degli eventi di trigger

Quando specifichi un filtro eventi, puoi indicare un'entità esatta una corrispondenza o un pattern del percorso. Utilizza un pattern di percorso per trovare corrispondenze con più entità con i caratteri jolly * o **.

Ad esempio, puoi specificare una corrispondenza esatta dell'entità per rispondere alle modifiche la seguente entità:

users/marie

Utilizza i caratteri jolly, * o **, per rispondere ai cambiamenti nelle entità che corrispondono a uno schema. Il carattere jolly * corrisponde a un singolo segmento e il carattere jolly a più segmenti ** corrisponde a zero o più segmenti nel pattern.

Per le corrispondenze di singoli segmenti (*), puoi anche utilizzare un gruppo di cattura denominato, ad esempio users/{userId}.

La seguente tabella mostra pattern di percorso validi:

Pattern Descrizione
users/* o users/{userId} Corrisponde a tutte le entità di tipo users. Non corrisponde al livello delle entità discendenti come /users/marie/messages/33e2IxYBD9enzS50SJ68
users/** Corrisponde a tutte le entità di tipo users e a tutte le entità discendenti come /users/marie/messages/33e2IxYBD9enzS50SJ68

Per scoprire di più sui pattern di percorso, consulta Pattern di percorso Eventarc.

L'attivatore deve sempre puntare a un'entità, anche se utilizzi un'espressione generica. Vedi i seguenti esempi:

  • users/{userId=*}/{messages=*} non è valido perché {messages=*} è un ID tipo.

  • users/{userId=*}/{messages}/{messageId=*} è valida perché {messageId=*} punta sempre a un'entità.

Sequenza di caratteri di escape

La sezione descrive le situazioni in cui è necessario utilizzare l'interpretazione letterale dei caratteri negli ID tipo e negli ID entità. L'inserimento di un carattere di escape consente al filtro dell'evento di interpretare correttamente l'ID.

  • Se un ID tipo o un ID entità include un carattere ~ o /, devi eseguire la codifica dell'ID nel filtro evento. Per eseguire l'escape di un ID, utilizza il formato__escENCODED_ID__. Sostituisci ENCODED_ID con un ID tipo o un ID entità in cui tutti i caratteri ~ e / sono sostituiti dai relativi ID codifica, che sono i seguenti:

    • ~: ~0
    • /: ~1

    Ad esempio, l'ID tipo user/profile diventa __escusers~1profile__. Un Esempio di pattern del percorso con questo ID tipo è __escusers~1profile__/{userId}

  • Se utilizzi l'ID tipo o l'ID entità di . o .. nel filtro eventi, devi eseguire l'interpretazione letterale dell'ID nel seguente modo:

    • .: __esc~2__
    • ..: __esc~2~2__

    Il carattere . deve essere preceduto da caratteri di escape solo se l'ID è esattamente . o ... Ad esempio, l'ID tipo customers.info non richiede caratteri di escape.

  • Se il tipo o l'ID entità è un valore numerico anziché una stringa, devi eseguire l'escape dell'ID con __idNUMERIC_VALUE__. Ad esempio, il pattern del percorso per un'entità di tipo 111 e con ID entità 222 è __id111__/__id222__.

  • Se hai eseguito la migrazione da Cloud Datastore precedente a Firestore in modalità Datastore, il tuo database potrebbe contenere ID precedenti in una codifica non UTF-8. Devi utilizzare l'interpretazione letterale di questi ID con __bytesBASE64_ENCODING__. Sostituisci BASE64_ENCODING con la codifica base-64 dell'ID. Ad esempio, il pattern di percorso Task/{task} con sfuggita per l'ID tipo non UTF-8Task diventa __bytesVGFzaw==__/{task}.

Funzioni di esempio

L'esempio seguente mostra come ricevere gli eventi in modalità Datastore. Per lavorare con i dati coinvolti in un evento, esamina i campi value e old_value.

  • value: un oggetto EntityResult che contiene un'istantanea dell'entità post-operazione. Questo campo non viene compilato per gli eventi di eliminazione.
  • old_value: un oggetto EntityResult che contiene un'entità pre-operation senza dover creare uno snapshot. Questo campo viene compilato solo per gli eventi di aggiornamento ed eliminazione.

Java

Per scoprire come installare e utilizzare la libreria client per la modalità Datastore, consulta Librerie client per la modalità Datastore. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Java in modalità Datastore.

Per eseguire l'autenticazione in modalità Datastore, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

import com.google.cloud.functions.CloudEventsFunction;
import com.google.events.cloud.datastore.v1.EntityEventData;
import com.google.protobuf.InvalidProtocolBufferException;
import io.cloudevents.CloudEvent;
import java.util.logging.Logger;

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

  @Override
  public void accept(CloudEvent event) throws InvalidProtocolBufferException {
    EntityEventData datastoreEventData = EntityEventData.parseFrom(event.getData().toBytes());

    logger.info("Function triggered by event on: " + event.getSource());
    logger.info("Event type: " + event.getType());

    logger.info("Old value:");
    logger.info(datastoreEventData.getOldValue().toString());

    logger.info("New value:");
    logger.info(datastoreEventData.getValue().toString());
  }
}

Includi le dipendenze proto nel codice sorgente

Devi includere la modalità Datastore data.proto nella directory di origine per la tua funzione. Questo file importa i seguenti dati che devi includere anche nella directory di origine:

Utilizza la stessa struttura di directory per le dipendenze. Ad esempio, posiziona struct.proto in google/protobuf.

Questi file sono necessari per decodificare i dati sugli eventi. Se l'origine della funzione non non include questi file, restituisce un errore durante l'esecuzione.

Attributi evento

Ogni evento include attributi dei dati che includono informazioni sull'evento, come l'ora in cui l'evento è stato attivato. Firestore in modalità Datastore aggiunge dati aggiuntivi sul database e sull'entità coinvolti nell'evento. Puoi accedere a questi attributi nel seguente modo:

Java
logger.info("Event time " + event.getTime());
logger.info("Event project: " + event.getExtension("project"));
logger.info("Event location: " + event.getExtension("location"));
logger.info("Database name: " + event.getExtension("database"));
logger.info("Database namespace: " + event.getExtension("namespace"));
logger.info("Database entity: " + event.getExtension("entity"));
// For withAuthContext events
logger.info("Auth information: " + event.getExtension("authid"));
logger.info("Auth information: " + event.getExtension("authtype"));

Esegui il deployment di una funzione

Gli utenti che eseguono il deployment delle funzioni Cloud Run devono avere Sviluppatore funzioni Cloud Run un ruolo IAM o un ruolo che include le stesse autorizzazioni. Consulta anche Configurazione aggiuntiva per il deployment.

Puoi eseguire il deployment di una funzione utilizzando la riga di comando gcloud o la console Google Cloud. L'esempio seguente mostra il deployment con l'interfaccia a riga di comando gcloud. Per maggiori dettagli sul deployment con la console Google Cloud, consulta Eseguire il deployment delle funzioni di Cloud Run.

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Utilizza il comando gcloud functions deploy per eseguire il deployment di una funzione:

    gcloud functions deploy FUNCTION_NAME \
    --gen2 \
    --region=FUNCTION_LOCATION \
    --trigger-location=TRIGGER_LOCATION \
    --runtime=RUNTIME \
    --source=SOURCE_LOCATION \
    --entry-point=CODE_ENTRYPOINT \
    --trigger-event-filters="type=EVENT_FILTER_TYPE" \
    --trigger-event-filters="database=DATABASE" \
    --trigger-event-filters="namespace=NAMESPACE" \
    --trigger-event-filters-path-pattern="entity=ENTITY_OR_PATH" \
    

    Il primo argomento, FUNCTION_NAME, è un nome per la funzione di cui è stato eseguito il deployment. Il nome della funzione deve iniziare con una lettera followed da un massimo di 62 lettere, numeri, trattini o trattini bassi e deve terminare con una lettera o un numero. Sostituisci FUNCTION_NAME con un valore valido il nome della funzione. Quindi, aggiungi i seguenti flag:

    • Il flag --gen2 specifica che vuoi eseguire il deployment su funzioni Cloud Run (2ª generazione). Omissione questo flag porta al deployment in Cloud Run Functions (1ª generazione.).

    • Il flag --region=FUNCTION_LOCATION specifica la regione in cui eseguire il deployment della funzione.

      Per massimizzare la prossimità, imposta FUNCTION_LOCATION su una regione vicino a del tuo database Firestore. Se il tuo database Firestore è in una località multiregionale, imposta il valore su us-central1 per i database innam5 e a europe-west4 per i database in eur3. Per regioni Località Firestore, impostate sulla stessa regione.

    • Il flag --trigger-location=TRIGGER_LOCATION specifica la posizione dell'attivatore. Devi impostare TRIGGER_LOCATION sulla località del database in modalità Datastore.

    • Il flag --runtime=RUNTIME specifica il runtime del linguaggio utilizzato dalla funzione. Funzioni di Cloud Run supporta diversi runtime. Consulta: Runtime per ulteriori informazioni. Imposta RUNTIME su un runtime supportato.

    • Il flag --source=SOURCE_LOCATION specifica la posizione del codice sorgente della funzione. Consulta quanto segue: per maggiori dettagli:

      Imposta SOURCE_LOCATION nella posizione del codice sorgente della funzione.

    • La --entry-point=CODE_ENTRYPOINT specifica il punto di ingresso della funzione nel codice sorgente. Questo è il codice che la tua funzione esegue durante l'esecuzione. Devi impostare CODE_ENTRYPOINT a un nome di funzione o una classe completa esistente nel codice sorgente. Per ulteriori informazioni, consulta Entry point della funzione.

    • I flag --trigger-event-filters definiscono il filtro degli eventi che include il tipo di attivatore e l'entità o il percorso che attiva gli eventi. Imposta i seguenti valori degli attributi per definire il filtro evento:

      • type=EVENT_FILTER_TYPE: Firestore supporta i seguenti tipi di eventi:

        • google.cloud.datastore.entity.v1.created: l'evento viene inviato quando viene scritta per la prima volta.
        • google.cloud.datastore.entity.v1.updated: l'evento viene inviato quando l'entità esiste già e ha un valore modificato.
        • google.cloud.datastore.entity.v1.deleted: l'evento viene inviato quando viene eliminata.
        • google.cloud.datastore.entity.v1.written: l'evento viene inviato quando viene creata, aggiornata o eliminata.
        • google.cloud.datastore.entity.v1.created.withAuthContext: l'evento è stato inviato quando un documento viene scritto per la prima volta e l'evento include informazioni di autenticazione aggiuntive
        • L'evento google.cloud.datastore.entity.v1.updated.withAuthContext viene inviato quando esiste già un documento e un valore è stato modificato. Include informazioni di autenticazione aggiuntive
        • L'evento google.cloud.datastore.entity.v1.deleted.withAuthContext viene inviato quando un documento viene eliminato. Include informazioni di autenticazione aggiuntive
        • google.cloud.datastore.entity.v1.written.withAuthContext: l'evento è stato inviato quando un documento viene creato, aggiornato o eliminato ed evento. Include informazioni di autenticazione aggiuntive

        Imposta EVENT_FILTER_TYPE su uno di questi tipi di eventi.

      • database=DATABASE: il database Firestore. Per il nome predefinito del database, imposta DATABASE su (default).

      • namespace=NAMESPACE: il database spazio dei nomi. Per il nome del database predefinito, imposta NAMESPACE su (default). Rimuovi il flag per fare corrispondere qualsiasi spazio dei nomi.

      • entity=ENTITY_OR_PATH: il percorso del database attiva eventi quando i dati vengono creati, aggiornati eliminati. I valori accettati per ENTITY_OR_PATH sono:

        • Uguale; ad esempio --trigger-event-filters="entity='users/marie'"
        • Pattern del percorso; ad esempio, --trigger-event-filters-path-pattern="entity='users/*'". Per saperne di più, consulta Comprendere i pattern dei percorsi.

      Facoltativamente, puoi specificare opzioni aggiuntive di configurazione, networking e sicurezza quando esegui il deployment di una funzione.

      Per un riferimento completo sul comando deployment e sui suoi flag, consulta gcloud functions deploy documentazione.

Esempi di implementazioni

I seguenti esempi mostrano i deployment con Google Cloud CLI.

Esegui il deployment di una funzione per un database nella regione us-west2:

gcloud functions deploy gcfv2-trigger-datastore-node \
--gen2 \
--region=us-west2 \
--trigger-location=us-west2 \
--runtime=nodejs18 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=makeUpperCase \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"

Esegui il deployment di una funzione per un database nella località multiregionale nam5:

gcloud functions deploy gcfv2-trigger-datastore-python \
--gen2 \
--region=us-central1 \
--trigger-location=nam5 \
--runtime=python311 \
--source=gs://example_bucket-1/datastoreEventFunction.zip \
--entry-point=make_upper_case \
--trigger-event-filters=type=google.cloud.datastore.entity.v1.written.withAuthContext \
--trigger-event-filters=database='(default)' \
--trigger-event-filters-path-pattern="entity='messages/{pushId}'"

Limitazioni

Tieni presente le seguenti limitazioni per i trigger di Firestore per le funzioni di Cloud Run:

  • Le funzioni Cloud Run (1ª gen.) richiedono un database "(default)" esistente in modalità nativa di Firestore. Non supportare i database denominati Firestore o la modalità Datastore. Utilizza le funzioni di Cloud Run (2ª generazione) per configurare gli eventi in questi casi.
  • L'ordine non è garantito. Modifiche rapide possono attivare chiamate di funzione in un ordine inaspettato.
  • Gli eventi vengono pubblicati almeno una volta, ma un singolo evento può generare più chiamate di funzione. Evita di fare affidamento su meccanismi di esecuzione esattamente una volta e scrivi funzioni idempotenti.
  • Firestore in modalità Datastore richiede Cloud Functions (2ª gen.). Le funzioni Cloud Run (1ª generazione.) non supportare la modalità Datastore.
  • Un trigger è associato a un singolo database. Non puoi creare un attivatore che corrisponda a più database.
  • L'eliminazione di un database non comporta l'eliminazione automatica degli attivatori per quel database. L'attivatore interrompe l'invio di eventi, ma continua a esistere finché non lo elimini.
  • Se un evento con corrispondenza supera la dimensione massima della richiesta, l'evento potrebbe non essere inviato alle funzioni Cloud Run (1ª gen.).
    • Gli eventi non consegnati a causa delle dimensioni della richiesta vengono registrati nei log della piattaforma e verranno conteggiate ai fini dell'utilizzo dei log da parte del progetto.
    • Puoi trovare questi log in Esplora log con il messaggio "L'evento non può recapitare a Funzione Cloud Functions a causa del superamento del limite per le dimensioni di 1ª generazione..." di error gravità. Puoi trovare il nome della funzione sotto il campo functionName. Se il campo receiveTimestamp è ancora entro un'ora da adesso, puoi dedurre i contenuti effettivi dell'evento leggendo il documento in questione con uno snapshot prima e dopo il timestamp.
    • Per evitare questa frequenza, puoi:
      • Esegui la migrazione e l'upgrade alle funzioni Cloud Run (2ª gen.)
      • Riduci le dimensioni del documento
      • Elimina le funzioni Cloud Run in questione
    • Puoi disattivare il logging utilizzando le esclusioni ma tieni presente che gli eventi offensivi non verranno comunque pubblicati.

Eventarc e Firestore in località in modalità Datastore

Eventarc non supporta le regioni multiple per gli attivatori di eventi Firestore, ma puoi comunque creare attivatori per i database Firestore in località multiregionali. Eventarc mappa le località Firestore in più regioni alle seguenti regioni Eventarc:

Firestore (più regioni) Regione Eventarc
nam5 us-central1
eur3 europe-west4

Passaggi successivi