С помощью Cloud Functions for Firebase вы можете обрабатывать события в Firebase SQL Connect. Cloud Functions позволяет выполнять серверный код в ответ на события, например на выполнение мутации в сервисе SQL Connect. Это позволяет добавлять собственную логику без развертывания собственных серверов.
Примеры использования
Синхронизация данных. Репликация или синхронизация данных с другими системами (например, Cloud Firestore, BigQuery или внешними API) после изменения.
Асинхронные рабочие процессы. Запускайте длительные процессы, такие как обработка изображений или агрегирование данных, после изменения базы данных.
Взаимодействие с пользователями. Отправляйте пользователям электронные письма или Cloud Messaging-уведомления после определенного события изменения в приложении, например создания аккаунта.
Как настроить триггер функции при изменении SQL Connect
Вы можете активировать функцию при каждом выполнении изменения SQL Connect с помощью обработчика событий onMutationExecuted. Этот триггер срабатывает при выполнении мутации.
Простая функция события изменения DOM
Ниже приведен простой пример функции, которая регистрирует сведения о любом изменении, выполненном в сервисе 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)
Если триггер срабатывает при любых изменениях в проекте, не выполняйте никаких изменений в обработчике триггера, иначе вы вызовете бесконечный цикл. Если вы хотите выполнить изменения в триггере события, используйте описанные ниже параметры фильтрации и убедитесь, что изменение не запускает само себя.
Как указать местоположение функции
Чтобы события запускали функцию, местоположение функции должно совпадать с местоположением сервиса SQL Connect. По умолчанию регион функции – 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
Введите фильтр
Обработчик 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 | authid |
|---|---|---|
| Конечный пользователь, прошедший аутентификацию | app_user |
UID токена Firebase Auth |
| Неаутентифицированный конечный пользователь | unauthenticated |
пусто |
| Admin SDK, выдающий себя за конечного пользователя | app_user
|
UID токена Firebase Auth пользователя, от имени которого выполняется действие. |
| 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 |
Полезная нагрузка события SQL Connect. Подробная информация приведена в следующем разделе. |
Полезная нагрузка данных
Объект MutationEventData содержит полезную нагрузку события 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– объект, содержащий переменные, которые были переданы в мутацию.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, событие SQL Connect не предоставляет снимок данных "до". Поскольку SQL Connect передает запросы в базовую базу данных, снимок данных "до" не может быть получен транзакционно. Вместо этого у вас есть доступ к аргументам, отправленным в мутацию, и данным, которые она вернула.
В частности, вы не можете сравнивать снимки "до" и "после", чтобы избежать бесконечных циклов, в которых триггер события вызывает то же самое событие. Если вам необходимо выполнить изменение из функции, активируемой событием изменения DOM, используйте фильтры событий и убедитесь, что изменение не может активировать само себя, даже косвенно.