С помощью Cloud Functions (2-го поколения) вы можете запускать функции в ответ на пользовательские события . Это события, предоставляемые специальными или дополнительными поставщиками событий, в отличие от событий 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)
# ...