Estendi Datastore con Cloud Functions (2nd gen)

Con Cloud Functions ed Eventarc, puoi eseguire il deployment del codice gestire gli eventi attivati da modifiche nel database Firestore in modalità Datastore. Questo ti consente di aggiungere funzionalità lato server senza utilizzare i tuoi server.

Trigger in modalità Datastore

Eventarc supporta il seguente evento Firestore in modalità Datastore che ti consentono di creare gestori Cloud Functions (2nd gen) collegati Eventi di Firestore in modalità Datastore:

Tipo di evento Trigger
google.cloud.datastore.entity.v1.created Attivato quando un'entità viene scritta per la prima volta.
google.cloud.datastore.entity.v1.updated Si attiva quando un'entità esiste già e ha un valore modificato.
google.cloud.datastore.entity.v1.deleted Attivato quando viene eliminata un'entità.
google.cloud.datastore.entity.v1.written Si attiva quando vengono attivati 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 Uguale a written, ma con l'aggiunta delle informazioni di autenticazione.

I trigger di eventi in modalità Datastore rispondono solo alle modifiche delle entità. Aggiornamento di un'entità in modalità Datastore in cui è invariato (una scrittura autonoma) non genera un evento di aggiornamento o scrittura. Tu non possono 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 altre e informazioni sull'entità che ha attivato l'evento. Aggiunge Attributi authtype e authid oltre alle informazioni restituite in l'evento di base. Consulta le authcontext per ulteriori informazioni sui valori degli attributi.

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 associare più entità a 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 acquisizione denominato, ad esempio come 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.

Il trigger deve sempre puntare a un'entità, anche se utilizzi un carattere jolly. 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 eseguire l'interpretazione letterale dei caratteri in di tipo e ID entità. L'utilizzo di caratteri di escape consente all'evento di filtrare correttamente interpretare l'ID.

  • Se un ID tipo o un ID entità include un carattere ~ o /, devi di escape all'ID nel filtro eventi. Per eseguire l'escape di un ID, utilizza il formato __escENCODED_ID__. Sostituisci ENCODED_ID con un ID tipo o un ID entità che contenga tutti i valori ~ e / caratteri sostituiti dai relativi ID codifica, che sono i seguenti:

    • ~: ~0
    • /: ~1

    Ad esempio, l'ID tipo user/profile diventa __escusers~1profile__. Un Il pattern di percorso di esempio 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é un valore stringa, devi eseguire il escape dell'ID con __idNUMERIC_VALUE__. Ad esempio, il pattern del percorso per un'entità di tipo 111 e ID entità 222 è __id111__/__id222__.

  • Se hai eseguito la migrazione da Cloud Datastore legacy a Firestore in modalità Datastore, il database potrebbe contenere ID legacy con una codifica non UTF8. Questi ID devono essere preceduti dal carattere di escape __bytesBASE64_ENCODING__. Sostituisci BASE64_ENCODING con la codifica Base64 dell'ID. Per Ad esempio, il pattern del percorso Task/{task} con caratteri di escape per l'ID di tipo non UTF8 Task 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, consulta i value e old_value campi.

  • value: un oggetto EntityResult che contiene uno snapshot 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 informazioni su come installare e utilizzare la libreria client per la modalità Datastore, consulta Librerie client in modalità Datastore. Per ulteriori informazioni, consulta API Java della modalità Datastore documentazione di riferimento.

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 nell'origine

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:

Usa 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 ulteriori dati 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 di Cloud Functions devono avere Sviluppatore Cloud Functions un ruolo IAM o un ruolo che include le stesse autorizzazioni. Vedi anche Configurazione aggiuntiva per il deployment.

Puoi eseguire il deployment di una funzione utilizzando gcloud CLI o la console Google Cloud. L'esempio seguente mostra il deployment con con gcloud CLI. Per maggiori dettagli sul deployment con la console Google Cloud, consulta Eseguire il deployment di Cloud Functions.

  1. Nella console Google Cloud, attiva Cloud Shell.

    Attiva Cloud Shell

    Nella parte inferiore della console Google Cloud viene avviata una sessione di Cloud Shell che mostra un prompt della riga di comando. Cloud Shell è un ambiente shell con Google Cloud CLI già installato e con valori già impostati per il progetto attuale. L'inizializzazione della sessione può richiedere alcuni secondi.

  2. Utilizza la 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 della funzione di cui hai eseguito il deployment. Il nome della funzione deve iniziare con una lettera seguito 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 Cloud Functions (2nd gen). Omissione questo flag porta al deployment in Cloud 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.

    • La --trigger-location=TRIGGER_LOCATION specifica la posizione del trigger. Devi impostare TRIGGER_LOCATION sulla località del database in modalità Datastore.

    • Il flag --runtime=RUNTIME specifica il runtime del linguaggio utilizzato dalla funzione. Cloud Functions 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. Consulta Punto di ingresso alla funzione per ulteriori informazioni.

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

      • 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 viene inviato quando un documento viene scritto per la prima volta e l'evento include informazioni di autenticazione aggiuntive
        • google.cloud.datastore.entity.v1.updated.withAuthContext: l'evento viene inviato quando un documento esiste già e ha un valore modificato. Include informazioni di autenticazione aggiuntive
        • google.cloud.datastore.entity.v1.deleted.withAuthContext: l'evento viene inviato quando un documento viene eliminato. Include informazioni di autenticazione aggiuntive
        • google.cloud.datastore.entity.v1.written.withAuthContext: l'evento viene 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 impostazione predefinita nome del database, imposta NAMESPACE su (default). Rimuovi la bandierina per 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 ulteriori configurazione, networking e le opzioni di sicurezza quando esegui il deployment di una funzione.

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

Deployment di esempio

I seguenti esempi dimostrano 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 Firestore per Cloud Functions:

  • Cloud Functions (1ª generazione.) prepara un prerequisito "(predefinito)" esistente in modalità nativa Firestore. Non supportare i database denominati Firestore o la modalità Datastore. Utilizza Cloud Functions (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ò comportare più chiamate di funzione. Da evitare in base a la meccanica "exactly-once" e scrivere funzioni idempotenti.
  • Firestore in modalità Datastore richiede Cloud Functions (2nd gen). Cloud Functions (1ª generazione) non supportare la modalità Datastore.
  • Un trigger è associato a un singolo database. Non puoi creare un trigger che corrisponde a più database.
  • L'eliminazione di un database non elimina automaticamente alcun trigger per quel database. La interrompe la pubblicazione degli eventi, ma continua a esistere finché non elimini l'attivatore.
  • Se un evento con corrispondenza supera le dimensioni massime della richiesta, il valore potrebbe non essere stato consegnato a Cloud Functions (1ª generazione.).
    • 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 Se il campo receiveTimestamp si trova ancora a meno di un'ora da adesso, puoi dedurre i contenuti dell'evento effettivo leggendo il documento in questione con una uno snapshot prima e dopo il timestamp.
    • Per evitare questa frequenza, puoi:
      • Esegui la migrazione e l'upgrade a Cloud Functions (2nd gen)
      • Ridimensiona il documento
      • Elimina le funzioni Cloud Functions 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 più regioni per l'evento Firestore ma puoi comunque creare trigger per i database Firestore in località multiregionali. Eventarc mappa Firestore località multiregionali alle seguenti regioni Eventarc:

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

Passaggi successivi