您可以為安裝擴充功能的使用者提供將自己的自訂邏輯插入擴充執行中的能力。有兩種方法可以實現此目的:
Eventarc 事件:為了提供使用者一種非同步回應事件的方法,您可以發佈到 Eventarc。使用者可以部署事件處理函數,例如在長時間運行的任務完成後發送通知,或者可以定義自己的後處理函數。
同步掛鉤:為了提供使用者一種向擴充功能添加阻塞邏輯的方法,您可以在擴充功能中的預定義點新增同步掛鉤。此時,您運行使用者提供者函數並僅在其完成後繼續。預處理任務通常屬於這一類。
擴展可以使用其中一種或兩種方法。
Eventarc 活動
要從擴充功能發布事件:
聲明您將在
extension.yaml
檔案中發布的事件類型:events: - type: publisher-id.extension-name.version.event-name description: event-description - type: publisher-id.extension-name.version.another-event-name description: another-event-description
type
標識符由幾個點分隔的欄位組成。發布者 ID 、擴充名稱和事件名稱欄位是必要的。建議使用版本字段。為您發佈的每種事件類型選擇一個唯一且具有描述性的事件名稱。例如,
storage-resize-images
擴展聲明單一事件類型:events: - type: firebase.extensions.storage-resize-images.v1.complete description: | Occurs when image resizing completes. The event will contain further details about specific formats and sizes.
用戶在安裝擴充功能時將能夠選擇訂閱哪些事件。
在您的擴充函數中,從 Admin SDK 匯入 Eventarc API 並使用使用者的安裝設定初始化事件通道。這些設定透過以下環境變數公開:
-
EVENTARC_CHANNEL
:使用者選擇向其發布事件的 Eventarc 通道的完全限定名稱。 -
EXT_SELECTED_EVENTS
:使用者選擇發佈的事件類型的逗號分隔清單。當您使用此值初始化通道時,Admin SDK 會自動過濾掉使用者未選擇的事件。 -
EVENTARC_CLOUD_EVENT_SOURCE
:雲端事件來源識別碼。 Admin SDK 會自動在已發佈事件的source
欄位中傳遞此值。您通常不需要明確使用此變數。
如果安裝時未啟用事件,這些變數將是未定義的。僅當啟用事件時,您才可以使用此事實來初始化事件通道:
import * as admin from "firebase-admin"; import {getEventarc} from 'firebase-admin/eventarc'; admin.initializeApp(); // Set eventChannel to a newly-initialized channel, or `undefined` if events // aren't enabled. const eventChannel = process.env.EVENTARC_CHANNEL && getEventarc().channel(process.env.EVENTARC_CHANNEL, { allowedEventTypes: process.env.EXT_SELECTED_EVENTS, });
-
將事件發佈到擴充功能中您想要向使用者公開的點處的通道。例如:
// If events are enabled, publish a `complete` event to the configured // channel. eventChannel && eventChannel.publish({ type: 'firebase.extensions.storage-resize-images.v1.complete', subject: filename, // the name of the original file data: { // ... } });
在 PREINSTALL 或 POSTINSTALL 檔案中記錄您發布的事件。
對於每個事件,記錄以下內容:
- 其預期目的
- 擴充程式邏輯中運行的點
- 它所包含的輸出數據
- 其執行條件
此外,警告使用者不要在事件處理程序中執行任何可能觸發相同擴展的操作,從而導致無限循環。
當您從擴充功能發布事件時,使用者可以部署事件處理程序以使用自訂邏輯進行回應。
例如,以下範例在調整大小後刪除原始影像。請注意,此範例處理程序使用了事件的subject
屬性,在本例中是映像的原始檔案名稱。
exports.onimageresized = onCustomEventPublished(
"firebase.extensions.storage-resize-images.v1.complete",
(event) => {
logger.info("Received image resize completed event", event);
// For example, delete the original.
return admin.storage()
.bucket("my-project.appspot.com")
.file(event.subject)
.delete();
});
有關詳細信息,請參閱自訂事件觸發器。
例子
官方的調整圖像大小擴展透過在調整圖像大小後發佈到 Eventarc 來提供非同步掛鉤。
同步鉤子
當您想要為使用者提供一個必須成功完成才能運行擴充函數之一的掛鉤時,請使用同步掛鉤。
同步掛鉤呼叫使用者定義的HTTPS 可呼叫雲函數,並在繼續之前等待完成(可能帶有返回值)。使用者提供的函數中的錯誤會導致擴展函數中的錯誤。
要公開同步鉤子:
在您的擴充功能中新增一個參數,允許使用者使用其自訂 Cloud Function 的 URL 配置擴充。例如:
- param: PREPROCESSING_FUNCTION label: Pre-processing function URL description: > An HTTPS callable function that will be called to transform the input data before it is processed by this function. type: string example: https://us-west1-my-project-id.cloudfunctions.net/preprocessData required: false
在擴充功能中想要公開掛鉤的位置,使用其 URL 呼叫該函數。例如:
const functions = require('firebase-functions'); const fetch = require('node-fetch'); const preprocessFunctionURL = process.env.PREPROCESSING_FUNCTION; exports.yourFunctionName = functions.firestore.document("collection/{doc_id}") .onWrite((change, context) => { // PREPROCESSING_FUNCTION hook begins here. // If a preprocessing function is defined, call it before continuing. if (preprocessFunctionURL) { try { await fetch(preprocessFunctionURL); // Could also be a POST request if you want to send data. } catch (e) { // Preprocessing failure causes the function to fail. functions.logger.error("Preprocessor error:", e); return; } } // End of PREPROCESSING_FUNCTION hook. // Main function logic follows. // ... });
記錄您在 PREINSTALL 或 POSTINSTALL 檔案中提供的任何掛鉤。
對於每個鉤子,記錄以下內容:
- 其預期目的
- 擴充程式邏輯中運行的點
- 其預期的輸入和輸出
- 其執行的條件(或選項)
另外,警告使用者不要在鉤子函數中執行任何可能觸發相同擴展的操作,從而導致無限循環。
例子
Algolia 搜尋擴充功能提供了一個同步掛鉤,可以在寫入 Algolia 之前呼叫使用者提供的轉換函數。