Estendi SQL Connect con Cloud Functions

Con Cloud Functions for Firebase, puoi gestire gli eventi in Firebase SQL Connect. Cloud Functions ti consente di eseguire codice lato server in risposta a eventi, ad esempio l'esecuzione di una mutazione nel tuo SQL Connect servizio. In questo modo puoi aggiungere logica personalizzata senza eseguire il deployment dei tuoi server.

Casi d'uso comuni

  • Sincronizzazione dei dati: replica o sincronizza i dati con altri sistemi (come Cloud Firestore, BigQuery o API esterne) dopo che si è verificata una mutazione.

  • Flussi di lavoro asincroni:avvia processi a lunga esecuzione, come l'elaborazione delle immagini o l'aggregazione dei dati, dopo una modifica del database.

  • Coinvolgimento degli utenti: invia email o Cloud Messaging notifiche agli utenti dopo un evento di mutazione specifico nella tua applicazione, ad esempio la creazione dell' account.

Attivare una funzione in caso di mutazione di SQL Connect

Puoi attivare una funzione ogni volta che viene eseguita una mutazione SQL Connect utilizzando il gestore di eventi onMutationExecuted. Questo trigger si verifica al momento dell'esecuzione di una mutazione.

Una funzione di eventi di mutazione di base

L'esempio di base seguente è una funzione che registra i dettagli di qualsiasi mutazione eseguita nel servizio SQL 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)

Quando attivi tutte le mutazioni nel tuo progetto, non devi eseguire alcuna mutazione nel gestore di trigger, altrimenti si verificherà un loop infinito. Se vuoi eseguire mutazioni in un trigger di eventi, utilizza le opzioni di filtro descritte di seguito e assicurati che la mutazione non si attivi da sola.

Impostare la località della funzione

La località della funzione deve corrispondere alla SQL Connect località del servizio affinché gli eventi attivino la funzione. Per impostazione predefinita, la regione della funzione è 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

Filtrare gli eventi

Il gestore onMutationExecuted può essere configurato con opzioni per filtrare gli eventi in base ad attributi specifici. Questa opzione è utile quando vuoi attivare la funzione solo per determinate mutazioni.

Puoi filtrare in base a service, connector e 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)

Caratteri jolly e gruppi di acquisizione

Puoi utilizzare caratteri jolly e gruppi di acquisizione per filtrare i trigger in base a più valori. Tutti i gruppi acquisiti sono disponibili in event.params per l'utilizzo. Per ulteriori informazioni, consulta la sezione Informazioni sui pattern di percorso.

Esempi:

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

Accedere alle informazioni sull'autenticazione utente

Puoi accedere alle informazioni sull'autenticazione utente dell'entità che ha attivato l'evento. Per ulteriori informazioni sui dati disponibili nel contesto di autenticazione, consulta la sezione Contesto di autenticazione.

L'esempio seguente mostra come recuperare le informazioni sull'autenticazione:

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

Il tipo di autenticazione e l'ID di autenticazione verranno compilati come segue:

Mutazione avviata da authtype authid
Utente finale autenticato app_user UID del token di Firebase Auth
Utente finale non autenticato unauthenticated vuoto
SDK Admin che simula l'identità di un utente finale app_user UID del token di Firebase Auth dell'utente simulato
SDK Admin che simula l'identità di una richiesta non autenticata unauthenticated vuoto
SDK Admin con tutte le autorizzazioni admin vuoto

Accedere ai dati sugli eventi

L'oggetto CloudEvent passato alla funzione contiene informazioni sull'evento che l'ha attivata.

Attributi evento

Attributo Tipo Descrizione
id string Identificatore univoco dell'evento.
source string La risorsa del connettore che ha generato l'evento (ad esempio, //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string La versione della specifica CloudEvents (ad es. "1.0").
type string Il tipo di evento: google.firebase.dataconnect.connector.v1.mutationExecuted.
time string Il timestamp (formato ISO 8601) di quando è stato generato l'evento.
subject string Facoltativo. Informazioni aggiuntive sul contesto dell'evento, come il nome dell'operazione.
params object Una mappa dei pattern di percorso acquisiti.
authType string Un'enumerazione che rappresenta il tipo di entità che ha attivato l'evento.
authId string Un identificatore univoco dell'entità che ha attivato l'evento.
data MutationEventData Il payload dell'evento SQL Connect. Vedi la sezione successiva.

Payload dei dati

L'oggetto MutationEventData contiene il payload dell'evento SQL 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 oggetto contenente le variabili passate alla mutazione.
  • payload.data: un oggetto contenente i dati restituiti dalla mutazione.
  • payload.errors: un array di eventuali errori che si sono verificati durante l'esecuzione della mutazione. Se la mutazione è andata a buon fine, questo array sarà vuoto.

Esempio

Ecco come puoi accedere alle variabili di mutazione e ai dati restituiti:

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

Tieni presente che, a differenza di altri trigger di database, come Cloud Firestore o Realtime Database, l'evento SQL Connect non fornisce uno snapshot "prima" dei dati. Poiché SQL Connect esegue il proxy delle richieste al database sottostante, lo snapshot "prima" dei dati non può essere ottenuto in modo transazionale. Invece, hai accesso agli argomenti inviati alla mutazione e ai dati restituiti.

Una conseguenza di questa situazione è che non puoi utilizzare la strategia di confronto degli snapshot "prima" e "dopo" per evitare loop infiniti, in cui un trigger di eventi attiva lo stesso evento. Se devi eseguire una mutazione da una funzione attivata da un evento di mutazione, utilizza i filtri degli eventi e assicurati che nessuna mutazione possa attivarsi, anche indirettamente.