Rozszerzanie Data Connect za pomocą Cloud Functions

Za pomocą Cloud Functions for Firebase możesz obsługiwać zdarzenia w Firebase Data Connect. Cloud Functions umożliwia uruchamianie kodu po stronie serwera w odpowiedzi na zdarzenia, takie jak wykonanie mutacji w usłudze Data Connect. Umożliwia to dodawanie niestandardowej logiki bez wdrażania własnych serwerów.

Typowe przypadki użycia

  • Synchronizacja danych: replikuj lub synchronizuj dane z innymi systemami (takimi jak Cloud Firestore, BigQuery lub zewnętrzne interfejsy API) po wystąpieniu mutacji.

  • Asynchroniczne przepływy pracy: Uruchamiają długotrwałe procesy, takie jak przetwarzanie obrazu lub agregacja danych, po zmianie bazy danych.

  • Zaangażowanie użytkowników: wysyłaj użytkownikom wiadomości e-mail lub powiadomienia Cloud Messaging po wystąpieniu określonego zdarzenia mutacji w aplikacji, takiego jak utworzenie konta.

Wyzwalanie funkcji na mutacji Data Connect

Możesz wyzwolić funkcję za każdym razem, gdy zostanie wykonana mutacja Data Connect, korzystając z obsługi zdarzeń onMutationExecuted. Ten wyzwalacz występuje po wykonaniu mutacji.

Podstawowa funkcja zdarzenia mutacji

Poniższy podstawowy przykład przedstawia funkcję, która rejestruje szczegóły każdej mutacji wykonanej w usłudze 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)

Podczas wyzwalania wszystkich mutacji w projekcie nie wolno wykonywać żadnych mutacji w procedurze obsługi wyzwalacza, gdyż spowoduje to pętlę nieskończoną. Jeśli chcesz dokonać mutacji w zdarzeniu wyzwalającym, użyj opcji filtrowania opisanych poniżej i upewnij się, że mutacja nie zostanie wyzwolona sama z siebie.

Ustawianie lokalizacji funkcji

Lokalizacja funkcji musi być zgodna z Data Connectlokalizacją usługi, aby zdarzenia wywoływały funkcję. Domyślny region funkcji to 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

Filtruj zdarzenia

onMutationExecuted można skonfigurować za pomocą opcji filtrowania zdarzeń na podstawie określonych atrybutów. Jest to przydatne, gdy chcesz wywoływać funkcję tylko w przypadku określonych mutacji.

Możesz filtrować według service, connector i 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)

Symbole wieloznaczne i grupy przechwytywania

Możesz używać symboli wieloznacznych i grup przechwytywania, aby filtrować wyzwalacze na podstawie wielu wartości. Wszystkie przechwycone grupy są dostępne w event.params. Więcej informacji znajdziesz w artykule Wyjaśnienie wzorców ścieżek.

Przykłady:

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

Uzyskiwanie dostępu do informacji o uwierzytelnianiu użytkowników

Możesz uzyskać dostęp do informacji o uwierzytelnianiu użytkownika dotyczących podmiotu, który wywołał zdarzenie. Więcej informacji o danych dostępnych w kontekście uwierzytelniania znajdziesz w artykule Kontekst uwierzytelniania.

Poniższy przykład pokazuje, jak pobrać informacje o uwierzytelnianiu:

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

Typ uwierzytelniania i identyfikator uwierzytelniania zostaną wypełnione w ten sposób:

Mutacja zainicjowana przez authtype authid
Uwierzytelniony użytkownik końcowy app_user Identyfikator UID tokenu uwierzytelniania Firebase
Niezautoryzowany użytkownik końcowy unauthenticated puste
Zestaw SDK administratora podszywający się pod użytkownika końcowego app_user Identyfikator UID tokenu uwierzytelniającego Firebase podszywającego się użytkownika
Pakiet SDK administratora podszywający się pod nieuwierzytelnione żądanie unauthenticated puste
Zestaw SDK administratora z pełnymi uprawnieniami admin puste

Dostęp do danych zdarzeń

Obiekt CloudEvent przekazany do Twojej funkcji zawiera informacje o zdarzeniu, które ją wyzwoliło.

Atrybuty zdarzeń

Atrybut Typ Opis
id string Unikalny identyfikator zdarzenia.
source string Zasób łącznika, który wygenerował zdarzenie (na przykład //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string Wersja specyfikacji CloudEvents (np. "1.0").
type string Typ zdarzenia: google.firebase.dataconnect.connector.v1.mutationExecuted.
time string Sygnatura czasowa (w formacie ISO 8601) określająca, kiedy wygenerowano wydarzenie.
subject string Opcjonalnie. Dodatkowe informacje o kontekście zdarzenia, np. nazwa operacji.
params object Mapa przechwyconych wzorców ścieżek.
authType string Wyliczenie reprezentujące typ podmiotu, który wyzwolił zdarzenie.
authId string Unikalny identyfikator podmiotu, który wyzwolił zdarzenie.
data MutationEventData Ładunek zdarzenia Data Connect. Zobacz następną sekcję.

Ładunek danych

Obiekt MutationEventData zawiera ładunek zdarzenia 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: Obiekt zawierający zmienne przekazane do mutacji.
  • payload.data: Obiekt zawierający dane zwrócone przez mutację.
  • payload.errors: Tablica wszystkich błędów, które wystąpiły podczas wykonywania mutacji. Jeśli mutacja się powiedzie, tablica będzie pusta.

Przykład

Aby uzyskać dostęp do zmiennych mutacji i zwróconych danych:

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

Pamiętaj, że w przeciwieństwie do niektórych innych wyzwalaczy bazy danych, takich jak Cloud Firestore lub Realtime Database, zdarzenie Data Connect nie zawiera migawki danych „przed”. Ponieważ Data Connect przekazuje żądania do podstawowej bazy danych, nie można uzyskać migawki danych „przed” transakcją. Zamiast tego masz dostęp do argumentów wysłanych do mutacji i danych, które ona zwróciła.

Jedną z konsekwencji tego jest to, że nie można stosować strategii porównywania migawek „przed” i „po” w celu uniknięcia pętli nieskończonych, w których wyzwalacz zdarzenia wyzwala to samo zdarzenie. Jeżeli musisz wykonać mutację z funkcji wyzwolonej przez zdarzenie mutacji, skorzystaj z filtrów zdarzeń i upewnij się, że żadna mutacja nie wywoła sama siebie, nawet pośrednio.