Activadores de Data Connect para Cloud Functions

Con Cloud Functions for Firebase, puedes controlar eventos en Firebase Data Connect. Cloud Functions te permite ejecutar código del lado del servidor en respuesta a eventos, como la ejecución de una mutación en tu servicio Data Connect. Esto te permite agregar lógica personalizada sin implementar tus propios servidores.

Casos de uso habituales

  • Sincronización de datos: Replica o sincroniza datos con otros sistemas (como Cloud Firestore, BigQuery o APIs externas) después de que se produce una mutación.

  • Flujos de trabajo asíncronos: Inicia procesos de larga duración, como el procesamiento de imágenes o la agregación de datos, después de un cambio en la base de datos.

  • Interacción del usuario: Enviar correos electrónicos o Cloud Messaging notificaciones a los usuarios después de un evento de mutación específico en su aplicación, como la creación de una cuenta.

Activa una función cuando se produzca una mutación de Data Connect

Puedes activar una función cada vez que se ejecute una mutación Data Connect usando el controlador de eventos onMutationExecuted. Este activador se activa cuando se ejecuta una mutación.

Una función básica de eventos de mutación

El siguiente ejemplo básico es una función que registra los detalles de cualquier mutación ejecutada en tu servicio 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)

Cuando se activan todas las mutaciones en tu proyecto, no debes realizar ninguna mutación en el controlador de activación, ya que provocarás un bucle infinito. Si deseas realizar mutaciones en un activador de eventos, usa las opciones de filtrado que se describen a continuación y asegúrate de que la mutación no se active por sí sola.

Configura la ubicación de la función

La ubicación de la función debe coincidir con la ubicación del servicio Data Connect para que los eventos activen la función. De forma predeterminada, la región de la función es 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

Filtrar eventos

El controlador onMutationExecuted se puede configurar con opciones para filtrar eventos según atributos específicos. Esto resulta útil cuando solo quieres activar tu función para ciertas mutaciones.

Puedes filtrar por service, connector y 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)

Comodines y grupos de captura

Puedes usar comodines y grupos de captura para filtrar tus activadores en función de varios valores. Los grupos capturados están disponibles en event.params para su uso. Consulta Información sobre los patrones de ruta de acceso para obtener más información.

Ejemplos:

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

Accede a la información de autenticación del usuario

Puedes acceder a la información de autenticación del usuario sobre el principal que activó el evento. Para obtener más información sobre los datos disponibles en el contexto de autenticación, consulta Contexto de autenticación.

En el siguiente ejemplo, se muestra cómo recuperar información de autenticación:

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

El tipo de autenticación y el ID de autenticación se completarán de la siguiente manera:

Mutación iniciada por authtype authid
Usuario final autenticado app_user UID del token de Firebase Auth
Usuario final no autenticado unauthenticated vacío
El SDK de Admin suplanta a un usuario final app_user UID del token de Firebase Auth del usuario suplantado
El SDK de Admin suplanta una solicitud no autenticada unauthenticated vacío
SDK de Admin con permisos completos admin vacío

Accede a los datos de eventos

El objeto CloudEvent que se pasa a tu función contiene información sobre el evento que la activó.

Atributos del evento

Atributo Tipo Descripción
id string Es un identificador único para el evento.
source string Es el recurso del conector que produjo el evento (por ejemplo, //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string La versión de la especificación de CloudEvents (p.ej., "1.0").
type string Tipo de evento: google.firebase.dataconnect.connector.v1.mutationExecuted.
time string La marca de tiempo (formato ISO 8601) de cuándo se produjo el evento.
subject string Opcional. Información adicional sobre el contexto del evento, como el nombre de la operación.
params object Mapa de los patrones de rutas capturados.
authType string Es una enumeración que representa el tipo de principal que activó el evento.
authId string Es un identificador único de la entidad principal que activó el evento.
data MutationEventData Es la carga útil del evento Data Connect. Consulta la siguiente sección.

Carga útil de datos

El objeto MutationEventData contiene la carga útil del evento 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: Un objeto que contiene las variables que se pasaron a la mutación.
  • payload.data: Un objeto que contiene los datos que devolvió la mutación.
  • payload.errors: Es un array de los errores que se produjeron durante la ejecución de la mutación. Si la mutación se realizó correctamente, este array estará vacío.

Ejemplo

A continuación, se muestra cómo puedes acceder a las variables de mutación y a los datos devueltos:

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

Tenga en cuenta que, a diferencia de otros activadores de bases de datos, como Cloud Firestore o Realtime Database, el evento Data Connect no proporciona una instantánea "anterior" de los datos. Dado que Data Connect reenvía solicitudes a la base de datos subyacente, la instantánea "anterior" de los datos no se puede obtener de forma transaccional. En cambio, tienes acceso a los argumentos enviados a la mutación y a los datos que esta devolvió.

Una consecuencia de esto es que no puedes usar la estrategia de comparar instantáneas "antes" y "después" para evitar bucles infinitos, en los que un activador de eventos activa el mismo evento. Si debes realizar una mutación desde una función activada por un evento de mutación, usa filtros de eventos y asegúrate de que ninguna mutación pueda activarse a sí misma, ni siquiera de forma indirecta.