SQL Connect mit Cloud Functions erweitern

Mit Cloud Functions for Firebase können Sie Ereignisse in Firebase SQL Connect verarbeiten. Mit Cloud Functions können Sie serverseitigen Code als Reaktion auf Ereignisse ausführen, z. B. die Ausführung einer Mutation in Ihrem SQL Connect-Dienst. So können Sie benutzerdefinierte Logik hinzufügen, ohne eigene Server bereitstellen zu müssen.

Gängige Anwendungsfälle

  • Datensynchronisierung: Daten nach einer Mutation mit anderen Systemen (wie Cloud Firestore, BigQuery oder externen APIs) replizieren oder synchronisieren.

  • Asynchrone Workflows: Starten Sie nach einer Datenbankänderung langwierige Prozesse wie die Bildverarbeitung oder Datenaggregation.

  • Nutzerinteraktion: Senden Sie Nutzern nach einem bestimmten Mutationsereignis in Ihrer Anwendung, z. B. der Kontoerstellung, E-Mails oder Cloud Messaging-Benachrichtigungen.

Funktion bei einer SQL Connect-Mutation auslösen

Sie können eine Funktion immer dann auslösen, wenn eine SQL Connect-Mutation mit dem Event-Handler onMutationExecuted ausgeführt wird. Dieser Trigger wird bei der Ausführung einer Mutation ausgelöst.

Eine einfache Funktion für Mutationsereignisse

Das folgende einfache Beispiel ist eine Funktion, die die Details aller Mutationen protokolliert, die in Ihrem SQL Connect-Dienst ausgeführt werden:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";

export const logMutation = onMutationExecuted(
  {
    /* Trigger on all mutations, spanning all services and connectors
       in us-central1 */
  },
  (event) => {
    logger.info("A mutation was executed!", {
      data: event.data,
    });
  }
);

Python

from firebase_functions import dataconnect_fn, logger

@dataconnect_fn.on_mutation_executed()
def log_mutation(event: dataconnect_fn.Event):
  logger.info("A mutation was executed!", event.data)

Wenn Sie alle Mutationen in Ihrem Projekt auslösen, dürfen Sie keine Mutationen im Trigger-Handler ausführen, da sonst eine Endlosschleife entsteht. Wenn Sie Mutationen in einem Ereignis-Trigger ausführen möchten, verwenden Sie die unten beschriebenen Filteroptionen und achten Sie darauf, dass die Mutation sich nicht selbst auslöst.

Funktionsstandort festlegen

Der Funktionsstandort muss mit dem SQL Connect-Dienststandort übereinstimmen, damit Ereignisse die Funktion auslösen. Die Standardregion der Funktion ist us-central1.

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";

export const onMutationRegionOption = onMutationExecuted(
  {
    region: "europe-west1"  // Set if SQL Connect service location is not us-central1
  },
  (event) => { /* ... */ }
);

Python

@dataconnect_fn.on_mutation_executed(
  region="europe-west1"  # Set if SQL Connect service location is not us-central1
)
def mutation_executed_handler_region_option(event: dataconnect_fn.Event):
  pass

Ereignisse filtern

Der onMutationExecuted-Handler kann mit Optionen konfiguriert werden, um Ereignisse anhand bestimmter Attribute zu filtern. Das ist nützlich, wenn Sie Ihre Funktion nur für bestimmte Mutationen auslösen möchten.

Sie können nach service, connector und operation filtern:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";

// Trigger this function only for the CreateUser mutation
// in the users connector of the myAppService service.
export const onUserCreate = onMutationExecuted(
  {
    service: "myAppService",
    connector: "users",
    operation: "CreateUser",
  },
  (event) => {
    logger.info("A new user was created!", event.data);
    // Add logic here: for example, sending a welcome email.
  }
);

Python

from firebase_functions import dataconnect_fn, logger

@dataconnect_fn.on_mutation_executed(
  service="myAppService",
  connector="users",
  operation="CreateUser"
):
def on_user_create(event: dataconnect_fn.Event):
  logger.info("A new user was created!", event.data)

Platzhalter und Erfassungsgruppen

Sie können Platzhalter und Erfassungsgruppen verwenden, um Ihre Trigger nach mehreren Werten zu filtern. Alle erfassten Gruppen sind in event.params verfügbar. Weitere Informationen finden Sie unter Informationen zu Pfadmustern.

Beispiele:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";

// Trigger on all operations that match the pattern `User*`, on any service and
// connector.
export const onMutationWildcards = onMutationExecuted(
  {
    operation: "User*",
  },
  (event) => {}
);

// Trigger on all operations that match the pattern `User*`, on any service and
// connector. Capture the operation name in the variable `op`.
export const onMutationCaptureWildcards = onMutationExecuted(
  {
    operation: "{op=User*}",
  },
  (event) => {
    // `event.params.op` contains the operation name.
  }
);

// Trigger on all operations on the service `myAppService`. Capture the
// operation name in the variable `operation`.
export const onMutationCaptures = onMutationExecuted(
  {
    service: "myAppService",
    operation: "{operation}",
  },
  (event) => {
    // `event.params.operation` contains the operation name.
  }
);

Python

from firebase_functions import dataconnect_fn

# Trigger on all operations that match the pattern `User*`, on any service and
# connector.
@dataconnect_fn.on_mutation_executed(
  operation="User*"
)
def on_mutation_wildcards(event: dataconnect_fn.Event):
  pass

# Trigger on all operations that match the pattern `User*`, on any service and
# connector. Capture the operation name in the variable `op`.
@dataconnect_fn.on_mutation_executed(
  operation="{op=User*}"
)
def on_mutation_capture_wildcards(event: dataconnect_fn.Event):
  # `event.params["op"]` contains the operation name.
  pass

# Trigger on all operations on the service `myAppService`. Capture the
# operation name in the variable `operation`.
@dataconnect_fn.on_mutation_executed(
  service="myAppService",
  operation="{operation}"
)
def on_mutation_captures(event: dataconnect_fn.Event):
  # `event.params["operation"]` contains the operation name.
  pass

Auf Informationen zur Nutzerauthentifizierung zugreifen

Sie können auf Nutzerauthentifizierungsinformationen zum Hauptkonto zugreifen, das das Ereignis ausgelöst hat. Weitere Informationen zu den im Authentifizierungskontext verfügbaren Daten finden Sie unter Authentifizierungskontext.

Das folgende Beispiel zeigt, wie Sie Authentifizierungsinformationen abrufen:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";

export const onMutation = onMutationExecuted(
  { operation: "MyMutation" },
  (event) => {
    // mutationExecuted event provides authType and authId:
    // event.authType
    // event.authId
  }
);

Python

from firebase_functions import dataconnect_fn

@dataconnect_fn.on_mutation_executed(operation="MyMutation")
def mutation_executed_handler(event: dataconnect_fn.Event):
  # mutationExecuted event provides auth_type and auth_id, which are accessed as follows
  # event.auth_type
  # event.auth_id
  pass

Der Authentifizierungstyp und die Authentifizierungs-ID werden so ausgefüllt:

Mutation initiiert von authtype authid
Authentifizierter Endnutzer app_user Firebase Auth-Token-UID
Nicht authentifizierter Endnutzer unauthenticated leer
Admin SDK, das sich als Endnutzer ausgibt app_user Firebase Auth-Token-UID des Nutzers, dessen Identität angenommen wurde
Admin SDK, das eine nicht authentifizierte Anfrage imitiert unauthenticated leer
Admin SDK mit allen Berechtigungen admin leer

Auf Ereignisdaten zugreifen

Das an Ihre Funktion übergebene CloudEvent-Objekt enthält Informationen zum Ereignis, durch das es ausgelöst wurde.

Ereignisattribute

Attribut Typ Beschreibung
id string Eine eindeutige Kennung für das Ereignis.
source string Die Connector-Ressource, die das Ereignis erzeugt hat (z. B. //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string Die CloudEvents-Spezifikationsversion (z.B. „1.0“).
type string Der Ereignistyp: google.firebase.dataconnect.connector.v1.mutationExecuted.
time string Der Zeitstempel (ISO 8601-Format) für den Zeitpunkt, zu dem das Ereignis erstellt wurde.
subject string Optional. Zusätzliche Informationen zum Ereigniskontext, z. B. der Vorgangsname.
params object Eine Zuordnung der erfassten Pfadmuster.
authType string Ein Enum, das den Typ des Hauptkontos darstellt, das das Ereignis ausgelöst hat.
authId string Eine eindeutige Kennung des Hauptkontos, das das Ereignis ausgelöst hat.
data MutationEventData Die Nutzlast des SQL Connect-Ereignisses. Weitere Informationen finden Sie im nächsten Abschnitt.

Datennutzlast

Das MutationEventData-Objekt enthält die Nutzlast des SQL Connect-Ereignisses:

{
  // ...
  "authType": // ...
  "data": {
    "payload": {
      "variables": {
        "userId": "user123",
        "updateData": {
          "displayName": "New Name"
        }
      },
      "data": {
        "updateUser": {
          "id": "user123",
          "displayName": "New Name",
          "email": "user@example.com"
        }
      },
      "errors": []
    }
  }
}
  • payload.variables: Ein Objekt, das die Variablen enthält, die an die Mutation übergeben wurden.
  • payload.data: Ein Objekt mit den Daten, die von der Mutation zurückgegeben wurden.
  • payload.errors: Ein Array aller Fehler, die während der Ausführung der Mutation aufgetreten sind. Wenn die Mutation erfolgreich war, ist dieses Array leer.

Beispiel

So können Sie auf die Mutationsvariablen und die zurückgegebenen Daten zugreifen:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";

export const processNewUserData = onMutationExecuted(
  {
    "service": "myAppService",
    "connector": "users",
    "operation": "CreateUser",
  },
  (event) => {
    // The variables passed to the mutation
    const mutationVariables = event.data.payload.variables;

    // The data returned by the mutation
    const returnedData = event.data.payload.data;

    logger.info("Processing mutation with variables:", mutationVariables);
    logger.info("Mutation returned:", returnedData);

    // ... your custom logic here
  }
);

Python

from firebase_functions import dataconnect_fn, logger

@dataconnect_fn.on_mutation_executed(
  service="myAppService",
  connector="users",
  operation="CreateUser"
):
def process_new_user_data(event: dataconnect_fn.Event):
  # The variables passed to the mutation
  mutation_vars = event.data.payload.variables
  # The data returned by the mutation
  returned_data = event.data.payload.data

  logger.info("Processing mutation with variables:", mutationVariables)
  logger.info("Mutation returned", returnedData)

  # ... your custom logic here

Im Gegensatz zu einigen anderen Datenbank-Triggern wie Cloud Firestore oder Realtime Database bietet das SQL Connect-Ereignis keinen „Vorher“-Snapshot der Daten. Da SQL Connect Anfragen an die zugrunde liegende Datenbank weiterleitet, kann der „Vorher“-Snapshot der Daten nicht transaktional abgerufen werden. Stattdessen haben Sie Zugriff auf die Argumente, die an die Mutation gesendet wurden, und die Daten, die von ihr zurückgegeben wurden.

Eine Folge davon ist, dass Sie die Strategie des Vergleichs von „Vorher“- und „Nachher“-Snapshots nicht verwenden können, um Endlosschleifen zu vermeiden, in denen ein Ereignis-Trigger dasselbe Ereignis auslöst. Wenn Sie eine Mutation von einer Funktion ausführen müssen, die durch ein Mutationsereignis ausgelöst wird, verwenden Sie Ereignisfilter und achten Sie darauf, dass sich eine Mutation niemals selbst auslösen kann, auch nicht indirekt.