С помощью Cloud Functions (второго поколения) можно запускать функции в ответ на специальные события. Это события, предоставляемые специальными или дополнительными поставщиками событий, а не события Firebase, изначально поддерживаемые Firebase SDK для Cloud Functions. С помощью триггеров специальных событий приложение может реагировать на события, предоставленные Firebase Extensions, или публиковать собственные специальные события и запускать функции в ответ на них.
Все специальные события соответствуют формату событий JSON CloudEvents и публикуются в Eventarc. Eventarc Взимается комиссия за использование.
Как запускать функции с помощью специальных событий
Вы можете публиковать специальные события (или получать события из расширений Firebase) и запускать функции в ответ на эти события, выполнив следующие действия:
- Опубликуйте нужные события в канале Eventarc или определите доступные события, предоставленные установленным расширением.
- В коде функции подпишитесь на события в канале Eventarc с помощью обработчика событий.
- В функции проанализируйте полезную нагрузку, возвращенную в объекте CloudEvent, и выполните любую пользовательскую логику, необходимую вашему приложению.
Например, приложение с игрой может отправлять пользователям уведомления, когда они входят в десятку лучших игроков или покидают ее. Это приложение может публиковать события, связанные с таблицей лидеров, в канал по умолчанию, а затем обрабатывать событие в функции, которая отправляет целевые push-уведомления пользователям.
Другой пример: расширение, предназначенное для обработки больших изображений в приложениях, может генерировать событие после завершения изменения размера изображения. Приложения с установленным расширением могут обрабатывать событие завершения, обновляя ссылки в приложении, чтобы они указывали на измененные версии изображений.
Как опубликовать мероприятие на канале
События Eventarc публикуются в каналах.
Каналы позволяют группировать связанные события и управлять разрешениями на доступ. Когда вы устанавливаете расширение или развертываете функцию, которая использует специальные события, Firebase автоматически создает канал по умолчанию с названием firebase в регионе us-central1. Firebase Admin SDK предоставляет eventarc-пакет для публикации на каналах.
Чтобы опубликовать событие с доверенного сервера (или из другой функции) с помощью канала по умолчанию:
import {getEventarc} from 'firebase-admin/eventarc';
getEventarc().channel().publish({
type: 'achieved-leaderboard',
subject: 'Welcome to the top 10',
data: {
message: 'You have achieved the nth position in our leaderboard! To see . . .'
}
});
Помимо автоматического создания канала по умолчанию, Firebase задает переменную среды EVENTARC_CLOUD_EVENT_SOURCE, которая указывает источник события. Если вы публикуете события за пределами Cloud Functions for Firebase, вам нужно явно добавить поле source в полезную нагрузку события.
Как обрабатывать специальные события
Вы можете обрабатывать все специальные события, в том числе события расширений, с помощью обработчиков onCustomEventPublished или on_custom_event_published. Сначала импортируйте этот обработчик из Eventarc SDK вместе с Firebase Admin SDK:
Node.js
const {onCustomEventPublished} = require("firebase-functions/eventarc");
const logger = require("firebase-functions/logger");
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");
Python
from firebase_admin import firestore, initialize_app
from firebase_functions import eventarc_fn
В коде функции передайте название события, как показано в примере ниже:
Node.js
exports.onimageresized = onCustomEventPublished(
"firebase.extensions.storage-resize-images.v1.complete",
(event) => {
logger.info("Received image resize completed event", event);
// For example, write resized image details into Firestore.
return getFirestore()
.collection("images")
.doc(event.subject.replace("/", "_")) // original file path
.set(event.data); // resized images paths and sizes
});
Python
@eventarc_fn.on_custom_event_published(
event_type="firebase.extensions.storage-resize-images.v1.complete"
)
def onimageresized(event: eventarc_fn.CloudEvent) -> None:
print("Received image resize completed event: ", event.type)
if not isinstance(event.subject, str):
print("No 'subject' data.")
return
# For example, write resized image details into Firestore.
firestore_client: google.cloud.firestore.Client = firestore.client()
collection = firestore_client.collection("images")
doc = collection.document(event.subject.replace("/", "_")) # original file path
doc.set(event.data) # resized images paths and sizes
Для каждого расширения полезная нагрузка, возвращаемая в объекте события, содержит данные, которые можно использовать для выполнения специальной логики в потоке приложения. В этом случае функция использует Admin SDK, чтобы скопировать метаданные об измененном изображении в коллекцию в Cloud Firestore, получив имя файла из subject, предоставленного событием, и сохранив метаданные из data, предоставленного событием.
Как публиковать и обрабатывать события на каналах, отличных от канала по умолчанию
Специальные каналы могут быть полезны, если вам нужны особые разрешения или другие требования и вы не хотите, чтобы все мероприятия имели одинаковый уровень заметности и доступа. Вы можете создать собственные каналы с помощью консоли Google Cloud. Публиковать и получать события можно только в одном канале.
Если специальное событие публикуется на канале, отличном от канала по умолчанию, вам нужно указать канал в коде функции. Например, если вы хотите обрабатывать события, опубликованные в канале, отличном от канала по умолчанию, для местоположения us-west1, вам нужно указать канал, как показано ниже:
Node.js
import { onCustomEventPublished } from "firebase-functions/v2/eventarc";
export const func = onCustomEventPublished(
{
eventType: "firebase.extensions.storage-resize-images.v1.complete",
channel: "locations/us-west1/channels/firebase",
region: "us-west1",
},
(event) => { ... });
Python
@eventarc_fn.on_custom_event_published(
event_type="firebase.extensions.storage-resize-images.v1.complete",
channel="locations/us-west1/channels/firebase",
region="us-west1",
)
def onimageresizedwest(event: eventarc_fn.CloudEvent) -> None:
print("Received image resize completed event: ", event.type)
# ...