Com o Cloud Functions for Firebase, é possível processar eventos em Firebase Data Connect. O Cloud Functions permite executar código do lado do servidor em resposta a eventos, como a execução de uma mutação no serviço Data Connect. Isso permite adicionar lógica personalizada sem implantar seus próprios servidores.
Casos de uso comuns
Sincronização de dados:replique ou sincronize dados com outros sistemas (como Cloud Firestore, BigQuery ou APIs externas) depois que uma mutação ocorrer.
Fluxos de trabalho assíncronos:iniciam processos de longa duração, como processamento de imagens ou agregação de dados, após uma mudança no banco de dados.
Engajamento do usuário:envie e-mails ou notificações Cloud Messaging aos usuários após um evento de mutação específico no seu aplicativo, como a criação de uma conta.
Acionar uma função em uma mutação de Data Connect
É possível acionar uma função sempre que uma mutação de Data Connect for executada
usando o manipulador de eventos onMutationExecuted. Esse gatilho ocorre na execução
de uma mutação.
Uma função básica de evento de mutação
O exemplo básico a seguir é uma função que registra os detalhes de qualquer mutação executada no serviço 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)
Ao acionar todas as mutações no seu projeto, não faça nenhuma mutação no manipulador de gatilho para evitar um loop infinito. Se você quiser fazer mutações em um gatilho de evento, use as opções de filtragem descritas abaixo e tome cuidado para que a mutação não se acione.
Definir o local da função
O local da função precisa corresponder ao local do serviço Data Connect para que os eventos acionem a função. Por padrão, a região da função é
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
O manipulador onMutationExecuted pode ser configurado com opções para filtrar eventos
com base em atributos específicos. Isso é útil quando você só quer acionar sua
função para determinadas mutações.
É possível filtrar por 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)
Caracteres curinga e grupos de captura
É possível usar caracteres curinga e grupos de captura para filtrar seus acionadores em vários valores. Todos os grupos capturados estão disponíveis em event.params para uso. Consulte Entender os padrões de caminho
para mais informações.
Exemplos:
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
Acessar informações de autenticação do usuário
Você pode acessar informações de autenticação do usuário sobre o principal que acionou o evento. Para mais informações sobre os dados disponíveis no contexto de autenticação, consulte Contexto da autenticação.
O exemplo a seguir demonstra como recuperar informações de autenticação:
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
O tipo e o ID de autenticação serão preenchidos da seguinte forma:
| Mutação iniciada por | authtype | authid |
|---|---|---|
| Usuário final autenticado | app_user |
UID do token do Firebase Auth |
| Usuário final não autenticado | unauthenticated |
vazio |
| SDK Admin representando um usuário final | app_user
|
UID do token do Firebase Auth do usuário representado. |
| O SDK Admin se passando por uma solicitação não autenticada | unauthenticated |
vazio |
| SDK Admin com permissões completas | admin |
vazio |
Acessar dados de eventos
O objeto CloudEvent transmitido para sua função contém informações sobre o
evento que a acionou.
Atributos do evento
| Atributo | Tipo | Descrição |
|---|---|---|
id |
string |
Um identificador exclusivo do evento. |
source
|
string
|
O recurso de conector que gerou o evento (por exemplo, //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*). |
specversion |
string |
A versão da especificação CloudEvents (por exemplo, "1.0"). |
type |
string |
O tipo do evento: google.firebase.dataconnect.connector.v1.mutationExecuted. |
time |
string |
O carimbo de data/hora (formato ISO 8601) de quando o evento foi produzido. |
subject |
string |
Opcional. Informações extras sobre o contexto do evento, como o nome da operação. |
params |
object |
Um mapa de padrões de caminhos capturados. |
authType |
string |
Uma enumeração que representa o tipo de principal que acionou o evento. |
authId |
string |
Um identificador exclusivo do principal que acionou o evento. |
data |
MutationEventData |
O payload do evento Data Connect. Consulte a próxima seção. |
Payload de dados
O objeto MutationEventData contém o payload do 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: um objeto que contém as variáveis transmitidas à mutação.payload.data: um objeto que contém os dados retornados pela mutação.payload.errors: uma matriz de erros que ocorreram durante a execução da mutação. Se a mutação for bem-sucedida, essa matriz vai estar vazia.
Exemplo
Veja como acessar as variáveis de mutação e os dados retornados:
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
Ao contrário de alguns outros acionadores de banco de dados, como Cloud Firestore ou Realtime Database, o evento Data Connect não fornece um snapshot "antes" dos dados. Como o Data Connect encaminha solicitações ao banco de dados subjacente, o snapshot "antes" dos dados não pode ser obtido de maneira transacional. Em vez disso, você tem acesso aos argumentos enviados à mutação e aos dados retornados por ela.
Uma consequência disso é que não é possível usar a estratégia de comparar snapshots "antes" e "depois" para evitar loops infinitos, em que um acionador de evento aciona o mesmo evento. Se você precisar realizar uma mutação de uma função acionada por um evento de mutação, use filtros de eventos e tome cuidado para garantir que nenhuma mutação possa se acionar, mesmo indiretamente.