С помощью Cloud Functions (2-го поколения) вы можете запускать функции в ответ на пользовательские события . Это события, предоставляемые специальными или дополнительными поставщиками событий, в отличие от событий Firebase, изначально поддерживаемых Firebase SDK для Cloud Functions . С помощью пользовательских триггеров событий ваше приложение может реагировать на события, предоставляемые Firebase Extensions , или вы можете публиковать собственные пользовательские события и запускать функции в ответ на них.
Все пользовательские события соответствуют формату событий CloudEvents JSON и публикуются в 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/v2/eventarc");
const logger = require("firebase-functions/logger");
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");
Питон
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
});
Питон
@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) => { ... });
Питон
@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)
# ...