Создание и обработка пользовательских триггеров событий

С помощью облачных функций (2-го поколения) вы можете запускать функции в ответ на пользовательские события . Это события, предоставляемые специальными или дополнительными поставщиками событий, в отличие от событий Firebase, которые изначально поддерживаются Firebase SDK для облачных функций. С помощью настраиваемых триггеров событий ваше приложение может реагировать на события, предоставляемые расширениями Firebase, или вы можете публиковать свои собственные настраиваемые события и запускать функции в ответ на них.

Все пользовательские события соответствуют формату событий CloudEvents JSON и публикуются в Eventarc . Взимается плата за использование Eventarc.

Триггерные функции с пользовательскими событиями

Вы можете публиковать пользовательские события (или получать события из расширений Firebase) и запускать функции в ответ на эти события, реализуя этот базовый процесс:

  1. Опубликуйте нужные события в канале Eventarc или определите доступные события, предоставляемые установленным вами расширением.
  2. В коде функции подпишитесь на события на канале Eventarc с помощью обработчика событий.
  3. В функции проанализируйте полезную нагрузку, возвращаемую в объекте 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)
    # ...