在擴充功能中新增使用者掛鉤

您可以讓安裝擴充功能的使用者,在執行擴充功能時插入自己的自訂邏輯。達成此目標的方法有兩種:

  • Eventarc 事件:如要讓使用者以非同步的方式回應事件,您可以將事件發布至 Eventarc。使用者可以部署事件處理常式函式,例如:在長時間執行的工作完成後傳送通知,或者可以定義自己的後續處理函式。

  • 同步掛鉤:如要讓使用者將封鎖邏輯新增至擴充功能,您可以在擴充功能作業的預先定義時間點新增同步掛鉤。這時,您會執行使用者供應器函式,直到執行完畢為止。預先處理工作通常就屬於這個類別。

擴充功能可以同時使用任一方法,或同時使用兩者。

Eventarc 事件

如何發布擴充功能中的事件:

  1. 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 是由數個以點分隔的欄位所組成。發布商 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.
    

    使用者在安裝擴充功能時,可以選擇要訂閱哪些事件。

  2. 請在擴充功能函式中,從 Admin SDK 匯入 Eventarc API,並使用使用者的安裝設定初始化事件管道。您可以透過下列環境變數公開這些設定:

    • EVENTARC_CHANNEL:使用者選擇發布事件的 Eventarc 管道完整名稱。
    • EXT_SELECTED_EVENTS:逗號分隔的列出使用者選擇發布的事件類型。使用這個值初始化管道時,Admin SDK 會自動篩除使用者並未選取的事件。
    • EVENTARC_CLOUD_EVENT_SOURCE:Cloud 事件來源 ID。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,
      });
    
  3. 在要向使用者公開的擴充功能時間點,將事件發布至管道。例如:

    // 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: {
          // ...
        }
    });
    
  4. 在 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();
    });

詳情請參閱「自訂事件觸發條件」一文。

範例

官方的 Resize Images 擴充功能可在調整圖片大小後發布至 Eventarc,提供非同步掛鉤。

同步掛鉤

如要為使用者提供必須成功完成的掛鉤,讓使用者能成功執行其中一項擴充功能函式,請使用同步掛鉤

同步掛鉤會呼叫使用者定義的 HTTPS 可呼叫 Cloud 函式,並等待完成 (可能具有傳回值),然後再繼續。使用者提供的函式錯誤會導致擴充功能函式發生錯誤。

如要公開同步掛鉤:

  1. 在擴充功能中新增參數,讓使用者使用自訂 Cloud 函式的網址設定擴充功能。例如:

    - 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
    
  2. 在擴充功能中要公開掛鉤的位置,使用其網址呼叫函式。例如:

    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.
          // ...
        });
    
  3. 記錄您在 PREINSTALL 或 POSTINSTALL 檔案中提供的任何掛鉤。

    針對每個掛鉤,記錄下列內容:

    • 其用途
    • 擴充功能邏輯中執行的點
    • 可預期輸入和輸出內容
    • 執行作業的條件 (或選項)

    此外,請提醒使用者不要在 hook 函式中,執行可能會觸發相同擴充功能的任何動作,否則將會產生無限迴圈。

範例

Algolia Search 擴充功能提供同步掛鉤,可在寫入 Algolia 之前呼叫使用者提供的轉換函式