Déclencheurs Data Connect pour Cloud Functions

Avec Cloud Functions for Firebase, vous pouvez gérer les événements dans Firebase Data Connect. Cloud Functions vous permet d'exécuter du code côté serveur en réponse à des événements, tels que l'exécution d'une mutation dans votre service Data Connect. Cela vous permet d'ajouter une logique personnalisée sans déployer vos propres serveurs.

Cas d'utilisation courants

  • Synchronisation des données : répliquez ou synchronisez les données avec d'autres systèmes (comme Cloud Firestore, BigQuery ou des API externes) après une mutation.

  • Workflows asynchrones : lancez des processus de longue durée, tels que le traitement d'images ou l'agrégation de données, après une modification de la base de données.

  • Engagement des utilisateurs : envoyez des e-mails ou des notifications Cloud Messaging aux utilisateurs après un événement de mutation spécifique dans votre application, comme la création d'un compte.

Déclencher une fonction sur une mutation Data Connect

Vous pouvez déclencher une fonction chaque fois qu'une mutation Data Connect est exécutée à l'aide du gestionnaire d'événements onMutationExecuted. Ce déclencheur se produit lors de l'exécution d'une mutation.

Fonction d'événement de mutation de base

L'exemple de base suivant est une fonction qui enregistre les détails de toute mutation exécutée dans votre service Data Connect :

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)

Lorsque vous déclenchez toutes les mutations de votre projet, vous ne devez effectuer aucune mutation dans le gestionnaire de déclencheur, sinon vous provoquerez une boucle infinie. Si vous souhaitez effectuer des mutations dans un déclencheur d'événement, utilisez les options de filtrage décrites ci-dessous et veillez à ce que la mutation ne se déclenche pas elle-même.

Définir l'emplacement de la fonction

L'emplacement de la fonction doit correspondre à l'emplacement du service Data Connect pour que les événements déclenchent la fonction. Par défaut, la région de la fonction est us-central1.

Node.js

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

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

Python

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

Filtrer les événements

Le gestionnaire onMutationExecuted peut être configuré avec des options permettant de filtrer les événements en fonction d'attributs spécifiques. Cela est utile lorsque vous ne souhaitez déclencher votre fonction que pour certaines mutations.

Vous pouvez filtrer les résultats par service, connector et operation :

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)

Caractères génériques et groupes de capture

Vous pouvez utiliser des caractères génériques et des groupes de capture pour filtrer vos déclencheurs sur plusieurs valeurs. Tous les groupes capturés sont disponibles dans event.params pour être utilisés. Voir Comprendre les modèles de chemin pour plus d'informations.

Exemples :

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

Accéder aux informations d'authentification des utilisateurs

Vous pouvez accéder aux informations d'authentification de l'utilisateur principal qui a déclenché l'événement. Pour en savoir plus sur les données disponibles dans le contexte d'authentification, consultez Contexte d'authentification.

L'exemple suivant montre comment récupérer des informations d'authentification :

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

Le type d'authentification et l'ID d'authentification seront renseignés comme suit :

Mutation initiée par authtype authid
Utilisateur final authentifié app_user UID du jeton Firebase Auth
Utilisateur final non authentifié unauthenticated vide
SDK Admin se faisant passer pour un utilisateur final app_user UID du jeton Firebase Auth de l'utilisateur imité
SDK Admin se faisant passer pour une requête non authentifiée unauthenticated vide
SDK Admin avec toutes les autorisations admin vide

Accéder aux données d'événement

L'objet CloudEvent transmis à votre fonction contient des informations sur l'événement qui l'a déclenchée.

Attributs d'événement

Attribut Type Description
id string Identifiant unique de l'événement.
source string Ressource de connecteur ayant généré l'événement (par exemple, //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string Version des spécifications CloudEvents (par exemple, "1.0").
type string Type d'événement : google.firebase.dataconnect.connector.v1.mutationExecuted.
time string Code temporel (au format ISO 8601) indiquant quand l'événement a été produit.
subject string Facultatif. Informations complémentaires sur le contexte de l'événement, comme le nom de l'opération.
params object Une carte des schémas de parcours capturés.
authType string Une énumération représentant le type de principal qui a déclenché l'événement.
authId string Identifiant unique du principal qui a déclenché l'événement.
data MutationEventData Charge utile de l'événement Data Connect. Consultez la section suivante.

charge utile de données

L'objet MutationEventData contient la charge utile de l'événement Data Connect :

{
  // ...
  "authType": // ...
  "data": {
    "payload": {
      "variables": {
        "userId": "user123",
        "updateData": {
          "displayName": "New Name"
        }
      },
      "data": {
        "updateUser": {
          "id": "user123",
          "displayName": "New Name",
          "email": "user@example.com"
        }
      },
      "errors": []
    }
  }
}
  • payload.variables : objet contenant les variables transmises à la mutation.
  • payload.data : objet contenant les données renvoyées par la mutation.
  • payload.errors : tableau des erreurs survenues lors de l'exécution de la mutation. Si la mutation a réussi, ce tableau sera vide.

Exemple

Voici comment accéder aux variables de mutation et aux données renvoyées :

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

Notez que contrairement à certains autres déclencheurs de base de données, tels que Cloud Firestore ou Realtime Database, l'événement Data Connect ne fournit pas un instantané « avant » des données. Étant donné que Data Connect sert de proxy pour les requêtes envoyées à la base de données sous-jacente, l'instantané "avant" des données ne peut pas être obtenu de manière transactionnelle. Vous avez en revanche accès aux arguments transmis à la mutation et aux données renvoyées par celle-ci.

Par conséquent, vous ne pouvez pas utiliser la stratégie de comparaison des instantanés "avant" et "après" pour éviter les boucles infinies, dans lesquelles un déclencheur d'événement déclenche le même événement. Si vous devez effectuer une mutation à partir d'une fonction déclenchée par un événement de mutation, utilisez des filtres d'événements et veillez à ce qu'aucune mutation ne puisse jamais se déclencher elle-même, même indirectement.