С помощью Cloud Functions for Firebase вы можете обрабатывать события в Firebase Data Connect . Cloud Functions позволяет запускать серверный код в ответ на события, например, при выполнении мутации в вашем сервисе Data Connect . Это позволяет добавлять собственную логику без развертывания собственных серверов.
Типичные сценарии использования
Синхронизация данных: репликация или синхронизация данных с другими системами (например, Cloud Firestore , BigQuery или внешними API) после возникновения изменений.
Асинхронные рабочие процессы: Запускайте длительные процессы, такие как обработка изображений или агрегация данных, после внесения изменений в базу данных.
Взаимодействие с пользователями: Отправляйте пользователям электронные письма или уведомления Cloud Messaging после определенного события изменения в вашем приложении, например, создания учетной записи.
Запустить функцию при изменении данных в Data Connect
Вы можете запустить функцию всякий раз, когда выполняется мутация Data Connect используя обработчик событий onMutationExecuted . Этот триггер срабатывает при выполнении мутации .
Базовая функция события мутации
Следующий простой пример представляет собой функцию, которая регистрирует подробности любых изменений, выполненных в вашей службе 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)
При запуске всех изменений в вашем проекте нельзя выполнять никаких изменений в обработчике триггера, иначе возникнет бесконечный цикл. Если вы хотите выполнять изменения в триггере события, используйте описанные ниже параметры фильтрации и убедитесь, что изменение не запускается само по себе.
Укажите местоположение функции
Для запуска функции событиями местоположение функции должно совпадать с местоположением службы Data Connect . По умолчанию регионом функции является 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
Фильтрация событий
Обработчик onMutationExecuted можно настроить с помощью параметров, позволяющих фильтровать события на основе определенных атрибутов. Это полезно, если вы хотите запускать свою функцию только для определенных мутаций.
Вы можете фильтровать по service , connector и 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)
Подстановочные символы и группы захвата
Вы можете использовать подстановочные знаки и группы захвата для фильтрации триггеров по нескольким значениям. Все захваченные группы доступны для использования в event.params . Дополнительную информацию см. в разделе «Понимание шаблонов путей» .
Примеры:
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
Доступ к информации для аутентификации пользователя
Вы можете получить доступ к информации об аутентификации пользователя, который инициировал событие. Дополнительную информацию о данных, доступных в контексте аутентификации, см. в разделе «Контекст аутентификации» .
Следующий пример демонстрирует, как получить информацию для аутентификации:
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
Тип аутентификации и идентификатор аутентификации будут заполнены следующим образом:
| Мутация, инициированная | authtype | аутид |
|---|---|---|
| Аутентифицированный конечный пользователь | app_user | UID токена аутентификации Firebase |
| Неаутентифицированный конечный пользователь | unauthenticated | пустой |
| Admin SDK имитирует действия конечного пользователя. | app_user | UID токена аутентификации Firebase для пользователя, от имени которого осуществляется операция аутентификации. |
| Административный SDK имитирует неаутентифицированный запрос. | unauthenticated | пустой |
| Административный SDK с полными правами доступа | admin | пустой |
Доступ к данным о событиях
Объект CloudEvent , переданный в вашу функцию, содержит информацию о событии, которое его вызвало.
Атрибуты события
| Атрибут | Тип | Описание |
|---|---|---|
id | string | Уникальный идентификатор мероприятия. |
source | string | Ресурс коннектора, который сгенерировал событие (например, //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/* ). |
specversion | string | Версия спецификации CloudEvents (например, "1.0"). |
type | string | Тип события: google.firebase.dataconnect.connector.v1.mutationExecuted . |
time | string | Отметка времени (в формате ISO 8601), указывающая на момент проведения мероприятия. |
subject | string | Необязательно. Дополнительная информация о контексте события, например, название операции. |
params | object | Карта зафиксированных траекторий движения. |
authType | string | Перечисление, представляющее тип субъекта, который инициировал событие. |
authId | string | Уникальный идентификатор субъекта, инициировавшего событие. |
data | MutationEventData | Полезная нагрузка события Data Connect . См. следующий раздел. |
Полезная нагрузка данных
Объект MutationEventData содержит полезную нагрузку события 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: Объект, содержащий переменные, переданные в функцию мутации.-
payload.data: Объект, содержащий данные, возвращенные в результате мутации. -
payload.errors: Массив ошибок, возникших во время выполнения мутации. Если мутация прошла успешно, этот массив будет пустым.
Пример
Вот как можно получить доступ к переменным мутации и возвращаемым данным:
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
Обратите внимание, что в отличие от некоторых других триггеров баз данных, таких как Cloud Firestore или Realtime Database , событие Data Connect не предоставляет «предварительный» снимок данных. Поскольку Data Connect перенаправляет запросы к базовой базе данных, «предварительный» снимок данных нельзя получить транзакционным путем. Вместо этого вы имеете доступ к аргументам, отправленным в мутацию, и к данным, которые были ею возвращены.
Одним из следствий этого является невозможность использования стратегии сравнения снимков «до» и «после» для предотвращения бесконечных циклов, в которых событие запускает одно и то же событие. Если вам необходимо выполнить изменение из функции, запускаемой событием изменения, используйте фильтры событий и позаботьтесь о том, чтобы никакое изменение никогда не могло запустить себя само, даже косвенно.