创建和处理自定义事件触发器

借助 Cloud Functions(第 2 代),您可以触发函数来响应自定义事件。这些事件来自特殊或其他事件提供方,与 Firebase SDK for Cloud Functions 原生支持的 Firebase 事件不同。通过自定义事件触发器,您的应用可以响应 Firebase Extensions 扩展程序提供的事件,您也可以发布自己的自定义事件并触发函数来响应这些事件。

所有自定义事件均符合 CloudEvents JSON 事件格式,并发布到 Eventarc。需支付 Eventarc 使用费

使用自定义事件来触发函数

通过实现以下基本流程,您可以发布自定义事件(或从 Firebase 扩展程序获取事件)并触发函数来响应这些事件:

  1. 将所需的事件发布到 Eventarc 渠道,或标识由已安装的扩展程序提供的可用事件。
  2. 在函数代码中,使用事件处理程序订阅 Eventarc 渠道上的事件。
  3. 在函数中,解析 CloudEvent 对象中返回的载荷,然后执行应用所需的任何自定义逻辑。

例如,游戏应用可能希望在用户进入或退出排行榜前十名时发送通知。此应用可以将排行榜事件发布到默认渠道,然后在一个函数中处理该事件,以便向用户发送有针对性的推送通知。

在另一个示例中,我们有一个协助应用处理大图片的扩展程序,它可能会在完成图片大小调整时发出一个事件。如果应用安装了此扩展程序,就可以在处理该事件时,将应用中的链接更新为指向调整后的图片。

将事件发布到渠道

Eventarc 事件会发布到渠道。 渠道是一种对相关事件进行分组以及管理访问权限的方式。当您安装扩展程序或部署处理自定义事件的函数时,Firebase 会自动在 us-central1 区域中创建名为 firebase 的默认渠道。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 字段。

处理自定义事件

您可以使用 onCustomEventPublishedon_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");

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 从事件提供的 subject 获取文件名,并保存事件提供的 data 中的元数据,从而将调整后图片的元数据复制到 Cloud Firestore 集合中。

在非默认渠道上发布和处理事件

如果您有特殊权限需求或其他需求,并且不希望所有事件具有相同级别的可见性和访问权限,则可以使用自定义渠道。您可以使用 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)
    # ...