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

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

Все пользовательские события соответствуют формату событий 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)
    # ...