С помощью 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,
});
}
);
Питон
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) => { /* ... */ }
);
Питон
@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.
}
);
Питон
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.
}
);
Питон
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
}
);
Питон
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
Тип аутентификации и идентификатор аутентификации будут заполнены следующим образом:
| Мутация, инициированная | тип авторизации | аутид |
|---|---|---|
| Аутентифицированный конечный пользователь | app_user | UID токена аутентификации Firebase |
| Неаутентифицированный конечный пользователь | unauthenticated | пустой |
| Admin SDK, выдающий себя за конечного пользователя | app_user | UID токена аутентификации Firebase для выдаваемого пользователя |
| Admin SDK имитирует неаутентифицированный запрос | unauthenticated | пустой |
| Admin 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
}
);
Питон
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 передаёт запросы к базовой базе данных, снимок данных «до» невозможно получить транзакционно. Вместо этого вы получаете доступ к аргументам, переданным мутации, и к данным, которые она вернула.
Одним из следствий этого является невозможность использовать стратегию сравнения снимков «до» и «после» для предотвращения бесконечных циклов, в которых событие-триггер запускает одно и то же событие. Если необходимо выполнить мутацию из функции, вызванной событием мутации, используйте фильтры событий и позаботьтесь о том, чтобы никакая мутация не могла запустить себя сама, даже косвенно.