使用 Cloud Functions (第 2 代) 時,您可以觸發函式來回應自訂事件。這些事件是由特殊或額外的事件供應商提供,而非 Firebase SDK for Cloud Functions 原生支援的 Firebase 事件。透過自訂事件觸發條件,應用程式可以回應 Firebase Extensions 提供的事件,也可以發布自己的自訂事件,並觸發函式來回應這些事件。
所有自訂事件都符合 CloudEvents JSON 事件格式,並發布至 Eventarc。Eventarc 須支付使用費。
透過自訂事件觸發函式
您可以發布自訂事件 (或從 Firebase 擴充功能取得事件),並實作下列基本流程,根據這些事件觸發函式:
- 將所需事件發布至 Eventarc 管道,或找出已安裝擴充功能提供的可用事件。
- 在函式程式碼中,使用事件處理常式訂閱 Eventarc 管道上的事件。
- 在函式中,剖析 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
欄位。
處理自訂事件
您可以使用 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");
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)
# ...