Datastore mit Cloud Functions (2. Generation) erweitern

Mit Cloud Run-Funktionen und Eventarc können Sie Code Ereignisse zu verarbeiten, die durch Änderungen in Ihrer Firestore-Datenbank im Datastore-Modus ausgelöst werden. Dieses ermöglicht es Ihnen, serverseitige Funktionen hinzuzufügen, ohne eigene Server betreiben zu müssen.

Trigger im Datastore-Modus

Eventarc unterstützt das folgende Ereignis in Firestore im Datastore-Modus Trigger, mit denen Sie Handler für Cloud Run-Funktionen (2. Generation) erstellen können, die mit Ereignisse in Firestore im Datastore-Modus:

Ereignistyp Trigger
google.cloud.datastore.entity.v1.created Wird ausgelöst, wenn eine Entität zum ersten Mal geschrieben wird.
google.cloud.datastore.entity.v1.updated Wird ausgelöst, wenn eine Entität bereits vorhanden ist und sich ein Wert geändert hat.
google.cloud.datastore.entity.v1.deleted Wird ausgelöst, wenn eine Entität gelöscht wird.
google.cloud.datastore.entity.v1.written Wird ausgelöst, wenn created, updated oder deleted ausgelöst wird.
google.cloud.datastore.entity.v1.created.withAuthContext Wie „created“, aber es werden Authentifizierungsinformationen hinzugefügt.
google.cloud.datastore.entity.v1.updated.withAuthContext Wie „updated“, aber es werden Authentifizierungsinformationen hinzugefügt.
google.cloud.datastore.entity.v1.deleted.withAuthContext Wie „deleted“, aber es werden Authentifizierungsinformationen hinzugefügt.
google.cloud.datastore.entity.v1.written.withAuthContext Wie „written“, aber es werden Authentifizierungsinformationen hinzugefügt.

Ereignistrigger im Datastore-Modus reagieren nur auf Entitätsänderungen. Eine Aktualisierung einer Entität im Datastore-Modus, bei der Daten unverändert ist (ein No-Op-Schreibvorgang) generiert kein Aktualisierungs- oder Schreibereignis. Sie können keine Ereignisse nur für bestimmte Properties generieren.

Authentifizierungskontext in das Ereignis aufnehmen

Wenn Sie zusätzliche Authentifizierungsinformationen zum Ereignis einbeziehen möchten, verwenden Sie einen Ereignistrigger mit der Erweiterung withAuthContext. Mit dieser Erweiterung werden zusätzliche Informationen zum Hauptkonto, das das Ereignis ausgelöst hat. Die Funktion fügt die authtype- und authid-Attribute zusätzlich zu den zurückgegebenen Informationen das Basisereignis. Weitere Informationen zu Attributwerten finden Sie in der Referenz authcontext.

Durch Entität ausgelöste Funktion schreiben

So schreiben Sie eine Funktion, die auf Ereignisse in Firestore im Datastore-Modus reagiert, Bereiten Sie sich vor, um während der Bereitstellung Folgendes anzugeben:

  • Triggerereignistyp
  • einen Triggerereignisfilter, um die mit der Funktion verknüpften Entitäten auszuwählen
  • Funktionscode für die Ausführung

Filter für Triggerereignisse

Wenn Sie einen Ereignisfilter festlegen, können Sie entweder eine genaue Entität oder ein Pfadmuster sein. Verwenden Sie ein Pfadmuster für den Abgleich mehrerer Entitäten mit die Platzhalter * oder **

Sie können beispielsweise eine genaue Entitätsübereinstimmung angeben, um auf Änderungen an der folgende Entität:

users/marie

Verwenden Sie den Platzhalter * oder **, um auf Änderungen an Entitäten zu reagieren die einem Muster entsprechen. Der Platzhalter * entspricht einem einzelnen Segment und der Platzhalter mit mehreren Segmenten ** entspricht null oder mehr Segmenten im Muster.

Für Übereinstimmungen mit einem einzelnen Segment (*) können Sie auch eine benannte Erfassungsgruppe wie users/{userId} verwenden.

In der folgenden Tabelle sind gültige Pfadmuster aufgeführt:

Muster Beschreibung
users/* oder users/{userId} Stimmt mit allen Entitäten der Art users überein. Stimmt nicht mit der Ebene von Nachfolgerentitäten wie /users/marie/messages/33e2IxYBD9enzS50SJ68 überein
users/** Führt zu Übereinstimmungen mit allen Entitäten vom Typ users und allen untergeordneten Entitäten wie /users/marie/messages/33e2IxYBD9enzS50SJ68.

Weitere Informationen zu Pfadmustern finden Sie unter Eventarc-Pfadmuster.

Ihr Trigger muss immer auf ein Element verweisen, auch wenn Sie einen Platzhalter verwenden. Betrachten Sie die folgenden Beispiele:

  • users/{userId=*}/{messages=*} ist ungültig, weil {messages=*} ist eine Art-ID.

  • users/{userId=*}/{messages}/{messageId=*} ist gültig, da {messageId=*} immer auf eine Entität verweist.

Maskierung von Zeichen

In diesem Abschnitt werden Situationen beschrieben, in denen Sie Zeichen in Art-IDs und Entitäts-IDs. Wenn Sie ein Zeichen mit Escapezeichen versehen, kann das Ereignis korrekt gefiltert werden. die ID zu interpretieren.

  • Wenn eine Art-ID oder Entitäts-ID das Zeichen ~ oder / enthält, müssen Sie die ID in Ihrem Ereignisfilter. Um eine ID zu maskieren, verwenden Sie das Format __escENCODED_ID__ Ersetzen Sie ENCODED_ID durch eine Art-ID oder eine Entitäts-ID, die alle ~- und /-Zeichen durch ihre folgenden Codierungs-IDs ersetzt:

    • ~: ~0
    • /: ~1

    Die Typ-ID user/profile wird beispielsweise zu __escusers~1profile__. Eine Beispiel für ein Pfadmuster mit dieser Art-ID ist __escusers~1profile__/{userId}

  • Wenn Sie die Art-ID oder Entitäts-ID von . oder .. in Ihrem Ereignisfilter verwenden, müssen Sie die ID so escapen:

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

    Sie müssen das Zeichen . nur dann maskieren, wenn die ID genau . oder .. lautet. Für die Art-ID customers.info ist beispielsweise kein Escapezeichen erforderlich.

  • Wenn Ihre Art- oder Entitäts-ID ein numerischer Wert anstelle eines Stringwerts ist, Sie müssen die ID mit __idNUMERIC_VALUE__ maskieren. Zum Beispiel das Pfadmuster für eine Entität vom Typ 111 und der Entitäts-ID 222. ist __id111__/__id222__.

  • Wenn Sie von der Legacy-Version von Cloud Datastore migriert haben auf Firestore im Datastore-Modus auswirkt, enthält Ihre Datenbank möglicherweise Legacy-IDs in einer Nicht-UTF8-Codierung. Diese IDs müssen mit dem Escapezeichen __bytesBASE64_ENCODING__ versehen werden. Ersetzen Sie BASE64_ENCODING durch die Base64-Codierung der ID. Für Beispiel: Das Pfadmuster Task/{task} mit Escapezeichen für Nicht-UTF8-Art-IDs Task wird zu __bytesVGFzaw==__/{task}.

Beispielfunktionen

Im folgenden Beispiel wird veranschaulicht, wie Ereignisse im Datastore-Modus empfangen werden. Wenn Sie mit den Daten eines Ereignisses arbeiten möchten, sehen Sie sich die value und old_value-Feldern.

  • value: Ein EntityResult-Objekt, das einen Entitäts-Snapshot vom Typ post-operation enthält. Dieses Feld wird bei Löschereignissen nicht ausgefüllt.
  • old_value: Ein EntityResult-Objekt, das eine Vor-Operation-Entität enthält. Snapshot. Dieses Feld wird nur für Aktualisierungs- und Löschereignisse ausgefüllt.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für den Datastore-Modus finden Sie unter Clientbibliotheken im Datastore-Modus. Weitere Informationen finden Sie in der Referenzdokumentation zur Datastore-Modus-Java API.

Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich beim Datastore-Modus zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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());
  }
}

Proto-Abhängigkeiten in die Quelle aufnehmen

Sie müssen den Datenspeichermodus data.proto einschließen im Quellverzeichnis für Ihre Funktion. Diese Datei importiert Folgendes Protos, die Sie auch in Ihr Quellverzeichnis aufnehmen müssen:

Verwenden Sie für die Abhängigkeiten dieselbe Verzeichnisstruktur. Beispiel: struct.proto in google/protobuf.

Diese Dateien sind erforderlich, um Ereignisdaten zu decodieren. Wenn Ihre Funktionsquelle diese Dateien nicht enthält, wird bei der Ausführung ein Fehler zurückgegeben.

Ereignisattribute

Jedes Ereignis enthält Datenattribute die Informationen zum Ereignis enthalten, z. B. die Uhrzeit, zu der das Ereignis ausgelöst wurde. Im Firestore im Datastore-Modus werden zusätzliche Daten zur Datenbank und zur Entität hinzugefügt, die am Ereignis beteiligt sind. So können Sie auf diese Attribute zugreifen:

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"));

Funktion bereitstellen

Nutzer, die Cloud Run-Funktionen bereitstellen, müssen die folgenden Berechtigungen haben: Entwickler von Cloud Run-Funktionen IAM-Rolle oder eine Rolle mit denselben Berechtigungen Siehe auch Zusätzliche Konfiguration für die Bereitstellung.

Sie können eine Funktion entweder über die gcloud CLI bereitstellen oder in der Google Cloud Console. Im folgenden Beispiel wird die Bereitstellung mit der gcloud CLI veranschaulicht. Weitere Informationen zur Bereitstellung mit der Google Cloud Console Siehe Cloud Run-Funktionen bereitstellen.

  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. Verwenden Sie den Befehl gcloud functions deploy, um eine Funktion bereitzustellen:

    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" \
    

    Das erste Argument, FUNCTION_NAME, ist ein Name für Ihre bereitgestellte Funktion. Der Name muss mit einem Buchstaben beginnen, gefolgt von bis zu 62 Buchstaben, Ziffern, Bindestrichen oder Unterstrichen. Das letzte Zeichen muss ein Buchstabe oder eine Ziffer sein. Ersetzen Sie FUNCTION_NAME durch einen gültigen Funktionsname. Fügen Sie dann die folgenden Flags hinzu:

    • Flag --gen2 gibt an, dass Sie Cloud Run-Funktionen (2nd gen) bereitstellen möchten. Auslassen Dieses Flag führt zur Bereitstellung für Cloud Run-Funktionen (1st gen).

    • Das Flag --region=FUNCTION_LOCATION gibt die Region an, in der die Funktion bereitgestellt werden soll.

      Wähle eine Region in der Nähe von FUNCTION_LOCATION aus, um die Entfernung zu maximieren. Ihrer Firestore-Datenbank. Wenn sich Ihre Firestore-Datenbank an einem multiregionalen Standort befindet, legen Sie den Wert für Datenbanken in nam5 auf us-central1 und für Datenbanken in eur3 auf europe-west4 fest. Für regionale Firestore-Standorte, die auf dieselbe Region festgelegt sind.

    • Die --trigger-location=TRIGGER_LOCATION gibt den Standort des Triggers an. Sie müssen für TRIGGER_LOCATION den Speicherort Ihrer Datenbank im Datastore-Modus festlegen.

    • Das Flag --runtime=RUNTIME gibt an, welche Sprachlaufzeit die Funktion verwendet. Cloud Run-Funktionen unterstützt mehrere Laufzeiten. Weitere Informationen finden Sie unter Weitere Informationen finden Sie unter Laufzeiten. Legen Sie für RUNTIME eine unterstützte Laufzeit fest.

    • Das Flag --source=SOURCE_LOCATION gibt den Speicherort des Quellcodes der Funktion an. Weitere Informationen: für weitere Informationen:

      Legen Sie für SOURCE_LOCATION den Speicherort des Funktionsquellcodes fest.

    • Das Flag --entry-point=CODE_ENTRYPOINT gibt den Einstiegspunkt für die Funktion in Ihrem Quellcode an. Dies ist den Code, den Ihre Funktion während der Ausführung ausführt. Sie müssen Folgendes festlegen: CODE_ENTRYPOINT auf einen Funktionsnamen oder eine voll qualifizierte Klasse der im Quellcode vorhanden ist. Weitere Informationen finden Sie unter Einstiegspunkt für Funktion für erhalten Sie weitere Informationen.

    • Die --trigger-event-filters Flags definieren den Ereignisfilter, der den Triggertyp und die Entität enthält oder Pfad, der die Ereignisse auslöst. Legen Sie die folgenden Attributwerte fest, um den Ereignisfilter zu definieren:

      • type=EVENT_FILTER_TYPE: Firestore unterstützt folgende Ereignistypen:

        • google.cloud.datastore.entity.v1.created: Ereignis wird gesendet, wenn ein Entity wird zum ersten Mal geschrieben.
        • google.cloud.datastore.entity.v1.updated: Dieses Ereignis wird gesendet, wenn eine Entität bereits vorhanden ist und sich ein Wert geändert hat.
        • google.cloud.datastore.entity.v1.deleted: Ereignis wird gesendet, wenn ein Entität gelöscht wird.
        • google.cloud.datastore.entity.v1.written: Ereignis wird gesendet, wenn ein Entität erstellt, aktualisiert oder gelöscht wird.
        • google.cloud.datastore.entity.v1.created.withAuthContext: Ereignis wurde gesendet Ein Dokument wird zum ersten Mal geschrieben und der Termin enthält zusätzliche Authentifizierungsinformationen
        • google.cloud.datastore.entity.v1.updated.withAuthContext: Ereignis wurde gesendet Wenn ein Dokument bereits vorhanden ist und sich ein Wert geändert hat. Enthält zusätzliche Authentifizierungsinformationen
        • google.cloud.datastore.entity.v1.deleted.withAuthContext: Ereignis wurde gesendet Ein Dokument wird gelöscht. Enthält zusätzliche Authentifizierungsinformationen
        • google.cloud.datastore.entity.v1.written.withAuthContext: Ereignis wurde gesendet Ein Dokument wird erstellt, aktualisiert oder gelöscht. Enthält zusätzliche Authentifizierungsinformationen

        Legen Sie EVENT_FILTER_TYPE auf einen dieser Ereignistypen fest.

      • database=DATABASE: Firestore-Datenbank. Legen Sie für den Standarddatenbanknamen DATABASE auf (default) fest.

      • namespace=NAMESPACE: die Datenbank namespace Für den Standardwert Datenbankname, legen Sie für NAMESPACE den Wert (default) fest. Kennzeichnung entfernen , um jedem Namespace zu entsprechen.

      • entity=ENTITY_OR_PATH: der Datenbankpfad, der Löst Ereignisse aus, wenn Daten erstellt, aktualisiert oder gelöscht. Zulässige Werte für ENTITY_OR_PATH sind:

        • Gleich. Beispiel: --trigger-event-filters="entity='users/marie'"
        • Pfadmuster. Beispiel: --trigger-event-filters-path-pattern="entity='users/*'". Weitere Informationen finden Sie unter Informationen zu Pfadmustern.

      Sie können optional weitere Konfigurations-, Netzwerk- und Sicherheitsoptionen angeben, wenn Sie eine Funktion bereitstellen.

      Eine vollständige Referenz zum Bereitstellungsbefehl und seinen Flags finden Sie in der Dokumentation zu gcloud functions deploy.

Beispielbereitstellungen

Die folgenden Beispiele zeigen Bereitstellungen mit der Google Cloud CLI.

Stellen Sie eine Funktion für eine Datenbank in der Region us-west2 bereit:

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}'"

Stellen Sie eine Funktion für eine Datenbank am multiregionalen Standort nam5 bereit:

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}'"

Beschränkungen

Beachten Sie die folgenden Einschränkungen für Firestore-Trigger für Cloud Run-Funktionen:

  • Für Cloud Run-Funktionen (1. Generation) ist ein vorhandener „(Standard)“ erforderlich im nativen Modus von Firestore verwenden. Nicht unterstützen benannte Firestore-Datenbanken oder den Datastore-Modus. Verwenden Sie Cloud Run-Funktionen (2. Generation), um in solchen Fällen Ereignisse zu konfigurieren.
  • Die Reihenfolge ist nicht garantiert. Schnelle Änderungen können Funktionsaufrufe in einer unvorhergesehenen Reihenfolge auslösen.
  • Ereignisse werden mindestens einmal übergeben. Ein einzelnes Ereignis kann aber zu mehreren Funktionsaufrufen führen. Vermeiden Sie die Abhängigkeit von genau einmal vorkommenden Verfahren und schreiben Sie idempotente Funktionen.
  • Firestore im Datastore-Modus erfordert Cloud Run-Funktionen (2nd gen). Cloud Run-Funktionen (1. Generation) unterstützen den Datastore-Modus.
  • Ein Trigger ist einer einzelnen Datenbank zugeordnet. Sie können keinen Trigger erstellen, der mit mehreren Datenbanken übereinstimmt.
  • Wenn Sie eine Datenbank löschen, werden nicht automatisch die Trigger für diese Datenbank gelöscht. Die Der Trigger liefert keine Ereignisse mehr. Er bleibt jedoch bestehen, bis Sie den Trigger löschen.
  • Überschreitet ein übereinstimmendes Ereignis die maximale Anfragegröße, wird das Ereignis wird möglicherweise nicht an Cloud Run-Funktionen (1st gen) gesendet.
    • Ereignisse, die aufgrund der Größe der Anfrage nicht zugestellt wurden, werden in Plattformlogs protokolliert und auf die Lognutzung für das Projekt angerechnet.
    • Sie finden diese Logs im Log-Explorer mit der Meldung "Ereignis kann nicht an die Cloud Functions-Funktion gesendet werden, da die Größe das Limit für die 1. Generation überschreitet..." mit dem Schweregrad error. Sie finden den Funktionsnamen unter dem Feld functionName. Wenn Das Feld receiveTimestamp befindet sich immer noch in einer Stunde, können Sie ableiten, des Veranstaltungsinhalts ansehen, indem Sie das entsprechende Dokument mit einem Snapshot vor und nach dem Zeitstempel.
    • So kannst du einen solchen Ablauf vermeiden:
      • Migrieren und Upgrade auf Cloud Run-Funktionen (2. Generation)
      • Dokument verkleinern
      • Betreffende Cloud Run-Funktionen löschen
    • Sie können das Logging selbst mithilfe von Ausschlüssen deaktivieren. Beachten Sie jedoch, dass die betreffenden Ereignisse dennoch nicht übermittelt werden.

Standorte für Eventarc und Firestore im Datastore-Modus

Eventarc unterstützt keine Mehrfachregionen für Firestore-Ereignisse Trigger, aber Sie können trotzdem Trigger für Firestore-Datenbanken erstellen an multiregionalen Standorten. Eventarc-Zuordnung in Firestore Multiregionale Standorte in die folgenden Eventarc-Regionen:

Firestore multiregional Eventarc-Region
nam5 us-central1
eur3 europe-west4

Nächste Schritte