開始建立擴充功能

本頁會逐步引導您建立簡易的 Firebase 擴充功能,讓您安裝在專案中或與他人分享。這個 Firebase 擴充功能的簡單範例會監控即時資料庫中的訊息,並將訊息轉換為大寫。

1. 設定環境並初始化專案

在開始建構擴充功能之前,您必須先使用必要工具設定建構環境。

  1. 安裝 Node.js 16 以上版本。安裝節點的其中一種方法是使用 nvm (或 nvm-windows)。

  2. 安裝或更新至最新版的 Firebase CLI。如要使用 npm 安裝或更新,請執行以下指令:

    npm install -g firebase-tools
    

現在使用 Firebase CLI 初始化新的擴充功能專案:

  1. 為擴充功能建立目錄,並在其中建立 cd

    mkdir rtdb-uppercase-messages && cd rtdb-uppercase-messages
    
  2. 執行 Firebase CLI 的 ext:dev:init 指令:

    firebase ext:dev:init
    

    系統提示時,請選擇 JavaScript 做為函式語言 (但請注意,您也可以在開發自己的擴充功能時使用 TypeScript)。當系統詢問您安裝依附元件時,請回答「是」。(接受所有其他選項的預設值)。這個指令會設定新擴充功能的基本架構程式碼集,方便您開始開發擴充功能。

2. 使用模擬器試用擴充功能範例

Firebase CLI 初始化新的擴充功能目錄時,會建立一個簡單的範例函式和 integration-tests 目錄,其中包含使用 Firebase 模擬器套件執行擴充功能所需的檔案。

嘗試在模擬器中執行範例擴充功能:

  1. 切換至 integration-tests 目錄:

    cd functions/integration-tests
    
  2. 使用示範專案啟動模擬器:

    firebase emulators:start --project=demo-test
    

    模擬器會將擴充功能載入到預先定義的「虛擬」專案 (demo-test)。目前為止,擴充功能包含單一 HTTP 觸發的函式 greetTheWorld,可在存取時傳回「hello world」訊息。

  3. 模擬器繼續執行時,請前往啟動模擬器時列印的網址,嘗試執行擴充功能的 greetTheWorld 函式。

    瀏覽器會顯示「Hello World from greet-the-world」訊息。

  4. 這個函式的原始碼位於擴充功能的 functions 目錄中。在所選的編輯器或 IDE 中開啟來源:

    functions/index.js

    const functions = require("firebase-functions");
    
    exports.greetTheWorld = functions.https.onRequest((req, res) => {
      // Here we reference a user-provided parameter
      // (its value is provided by the user during installation)
      const consumerProvidedGreeting = process.env.GREETING;
    
      // And here we reference an auto-populated parameter
      // (its value is provided by Firebase after installation)
      const instanceId = process.env.EXT_INSTANCE_ID;
    
      const greeting = `${consumerProvidedGreeting} World from ${instanceId}`;
    
      res.send(greeting);
    });
    
  5. 模擬器執行期間,會自動重新載入您對函式程式碼所做的任何變更。請嘗試稍微變更 greetTheWorld 函式:

    functions/index.js

    const greeting = `${consumerProvidedGreeting} everyone, from ${instanceId}`;
    

    儲存變更。模擬器會重新載入程式碼,現在您造訪函式網址時,就會看到更新後的問候語。

3. 為 extension.yaml 新增基本資訊

現在您已設定開發環境,也執行擴充功能模擬器,可以開始編寫自己的擴充功能。

第一步是編輯預先定義的擴充功能中繼資料,以反映您要寫入的擴充功能,而非 greet-the-world。這項中繼資料會儲存在 extension.yaml 檔案中。

  1. 在編輯器中開啟 extension.yaml,然後將檔案的全部內容替換成以下內容:

    name: rtdb-uppercase-messages
    version: 0.0.1
    specVersion: v1beta  # Firebase Extensions specification version; don't change
    
    # Friendly display name for your extension (~3-5 words)
    displayName: Convert messages to upper case
    
    # Brief description of the task your extension performs (~1 sentence)
    description: >-
      Converts messages in RTDB to upper case
    
    author:
      authorName: Your Name
      url: https://your-site.example.com
    
    license: Apache-2.0  # Required license
    
    # Public URL for the source code of your extension
    sourceUrl: https://github.com/your-name/your-repo
    

    請注意 name 欄位中使用的命名慣例:官方 Firebase 擴充功能的名稱會以前置字元命名,指出擴充功能執行的主要 Firebase 產品,然後說明擴充功能的用途。建議您在額外資訊中採用相同的慣例。

  2. 由於您變更了擴充功能名稱,因此也應使用新名稱更新模擬器設定:

    1. functions/integration-tests/firebase.json 中,將 greet-the-world 變更為 rtdb-uppercase-messages
    2. functions/integration-tests/extensions/greet-the-world.env 重新命名為 functions/integration-tests/extensions/rtdb-uppercase-messages.env

擴充功能程式碼中仍有部分 greet-the-world 擴充功能剩餘項目,但請先保留。您將在接下來的幾個章節中更新這些項目。

4. 編寫 Cloud 函式並宣告為擴充功能資源

您現在可以開始編寫程式碼了。在這個步驟中,您將編寫用於執行擴充功能核心工作的 Cloud 函式,該函式會觀察即時資料庫中的訊息,並將訊息轉換為大寫。

  1. 在您選擇的編輯器或 IDE 中開啟擴充功能函式的來源 (位於擴充功能的 functions 目錄中)。將內容改為以下內容:

    functions/index.js

    import { database, logger } from "firebase-functions/v1";
    
    const app = initializeApp();
    
    // Listens for new messages added to /messages/{pushId}/original and creates an
    // uppercase version of the message to /messages/{pushId}/uppercase
    // for all databases in 'us-central1'
    export const makeuppercase = database
      .ref("/messages/{pushId}/uppercase")
      .onCreate(async (snapshot, context) => {
        // Grab the current value of what was written to the Realtime Database.
        const original = snapshot.val();
    
        // Convert it to upper case.
        logger.log("Uppercasing", context.params.pushId, original);
        const uppercase = original.toUpperCase();
    
        // Setting an "uppercase" sibling in the Realtime Database.
        const upperRef = snapshot.ref.parent.child("upper");
        await upperRef.set(uppercase);
    });
    

    您替換的舊函式是 HTTP 觸發的函式,會在存取 HTTP 端點時執行。新函式會由即時資料庫事件觸發:監控特定路徑中的新項目,偵測到時,它會將大寫版本的值寫回資料庫。

    順帶一提,這個新檔案使用 ECMAScript 模組語法 (importexport),而非 CommonJS (require)。如要在 Node 中使用 ES 模組,請在 functions/package.json 中指定 "type": "module"

    {
      "name": "rtdb-uppercase-messages",
      "main": "index.js",
      "type": "module",
      …
    }
    
  2. 擴充功能中的每個函式都必須在 extension.yaml 檔案中宣告。範例擴充功能宣告了 greetTheWorld 為擴充功能的唯一 Cloud 函式;您已將其替換為 makeuppercase,因此您也必須更新其宣告。

    開啟 extension.yaml 並新增 resources 欄位:

    resources:
      - name: makeuppercase
        type: firebaseextensions.v1beta.function
        properties:
          eventTrigger:
            eventType: providers/google.firebase.database/eventTypes/ref.create
            # DATABASE_INSTANCE (project's default instance) is an auto-populated
            # parameter value. You can also specify an instance.
            resource: projects/_/instances/${DATABASE_INSTANCE}/refs/messages/{pushId}/original
          runtime: "nodejs18"
    
  3. 由於你的擴充功能現已使用即時資料庫做為觸發條件,因此你必須更新模擬器設定,才能執行 RTDB 模擬器和 Cloud Functions 模擬器:

    1. 如果模擬器仍在執行,請按下 Ctrl-C 鍵停止執行,

    2. functions/integration-tests 目錄執行下列指令:

      firebase init emulators
      

      系統詢問時,請略過預設專案設定,然後選取函式和資料庫模擬器。接受預設通訊埠,並允許設定工具下載任何必要檔案。

    3. 重新啟動模擬器:

      firebase emulators:start --project=demo-test
      
  4. 試用更新版擴充功能:

    1. 使用模擬器啟動時列印的連結,開啟資料庫模擬器 UI。

    2. 編輯資料庫的根節點:

      • 欄位: messages
      • 類型: json
      • 值: {"11": {"original": "recipe"}}

      如果一切都正確設定,當您儲存資料庫變更後,擴充功能的 makeuppercase 函式應會觸發,並在訊息 11 中加入子項記錄,其中含有 "upper": "RECIPE" 內容。查看記錄和模擬器 UI 的資料庫分頁,確認預期的結果。

    3. 嘗試新增更多子項至 messages 節點 ({"original":"any text"})。當您新增記錄時,擴充功能應新增 uppercase 欄位,其中包含 original 欄位的大寫內容。

現在,您已擁有可在 RTDB 執行個體上運作的完整 (但簡單) 擴充功能。在後續各節中,您將使用一些其他功能來修正這個擴充功能。接著,準備將擴充功能發布給其他使用者,最後瞭解如何在 Extensions Hub 上發布擴充功能。

5. 宣告 API 和角色

Firebase 會使用個別執行個體的服務帳戶,將已安裝擴充功能的每個執行個體授予專案及其資料的有限存取權。每個帳戶都具備運作所需的最低權限。因此,您必須明確宣告擴充功能所需的任何 IAM 角色;使用者安裝擴充功能時,Firebase 會建立具有這些角色的服務帳戶,並使用該帳戶執行擴充功能。

您不需要宣告角色即可觸發產品的事件,但您必須宣告角色才能與其互動。由於您在最後一個步驟中新增的函式會寫入即時資料庫,因此您必須在 extension.yaml 中新增下列宣告:

roles:
  - role: firebasedatabase.admin
    reason: Allows the extension to write to RTDB.

同樣地,您也可以在 apis 欄位中宣告擴充功能使用的 Google API。使用者安裝擴充功能時,系統會詢問是否要自動為專案啟用這些 API。這通常只有非 Firebase Google API 才有必要,在本指南中並不需要。

6. 定義可由使用者設定的參數

您在最後兩個步驟中建立的函式,會觀看傳入訊息的特定 RTDB 位置。有時候,觀看特定位置其實就是您想要的,例如當擴充功能在擴充功能專用的資料庫結構上執行時。但在大部分情況下,您可能會希望在專案中安裝擴充功能的使用者設定這些值。這樣一來,使用者就可以使用您的擴充功能,搭配現有的資料庫設定。

讓擴充功能透過可由使用者設定的新訊息監控路徑:

  1. extension.yaml 檔案中,新增 params 區段:

    - param: MESSAGE_PATH
      label: Message path
      description: >-
        What is the path at which the original text of a message can be found?
      type: string
      default: /messages/{pushId}/original
      required: true
      immutable: false
    

    這會定義新的字串參數,系統會在使用者安裝擴充功能時提示使用者設定。

  2. 同樣在 extension.yaml 檔案中,返回 makeuppercase 宣告,並將 resource 欄位變更為以下內容:

    resource: projects/_/instances/${DATABASE_INSTANCE}/refs/${param:MESSAGE_PATH}
    

    ${param:MESSAGE_PATH} 權杖是您剛定義的參數的參照。擴充功能執行時,這個權杖會替換為使用者針對該參數設定的任何值,結果 makeuppercase 函式將監聽使用者指定的路徑。您可以使用這個語法參照 extension.yaml 中任何位置 (以及稍後在 POSTINSTALL.md 中) 的任何使用者定義參數。

  3. 您也可以透過函式程式碼存取使用者定義的參數。

    在上一節編寫的函式中,您已使用硬式編碼路徑來查看變更。請將觸發條件定義改為參照使用者定義的值:

    functions/index.js

    export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate
    

    請注意,在 Firebase Extensions 中,這項變更純粹是為了提供說明文件:當 Cloud 函式部署為擴充功能的一部分時,會使用 extension.yaml 檔案的觸發條件定義,並忽略函式定義中指定的值。不過,建議您在程式碼中記錄這個值的來源。

  4. 您可能會在變更未在執行階段生效的情況下進行程式碼變更,可能會感到失望,但重點是您可以存取函式程式碼中的任何使用者定義參數,並將該參數用做函式邏輯中的一般值。為提供這項功能,請新增下列記錄陳述式,以證明您確實存取了使用者定義的值:

    functions/index.js

    export const makeuppercase = database.ref(process.env.MESSAGE_PATH).onCreate(
      async (snapshot, context) => {
        logger.log("Found new message at ", snapshot.ref);
    
        // Grab the current value of what was written to the Realtime Database.
        ...
    
  5. 一般而言,系統會在使用者安裝擴充功能時,提示使用者提供參數值。不過,當您使用模擬器進行測試和開發時,可以略過安裝程序,所以改用 env 檔案提供使用者定義的參數值。

    開啟 functions/integration-tests/extensions/rtdb-uppercase-messages.env,並將 GREETING 定義替換為下列內容:

    MESSAGE_PATH=/msgs/{pushId}/original
    

    請注意,上述路徑與預設路徑和您先前定義的路徑不同;這只是在嘗試更新後的擴充功能,且定義生效時向您證明。

  6. 現在,重新啟動模擬器,然後再次造訪資料庫模擬器 UI。

    使用您在上方定義的路徑編輯資料庫的根節點:

    • 欄位: msgs
    • 類型: json
    • 值: {"11": {"original": "recipe"}}

    儲存資料庫變更時,擴充功能的 makeuppercase 函式應如往常一樣觸發,但現在應該還會顯示使用者定義的參數到主控台記錄中。

7. 為使用者定義的邏輯提供事件掛鉤

身為擴充功能作者,您已瞭解 Firebase 產品如何觸發擴充功能提供的邏輯:在即時資料庫中建立新記錄會觸發 makeuppercase 函式。您的擴充功能可與安裝擴充功能的使用者類似,也就是您的擴充功能可能會觸發 user 定義的邏輯。

擴充功能可以提供同步掛鉤非同步掛鉤,或同時提供這兩種機制。同步掛鉤可讓使用者執行工作,阻止擴充功能的其中一項函式完成。舉例來說,如要讓使用者在擴充功能執行前執行自訂預先處理作業,這個做法會很實用。

在這個指南中,您會將非同步掛鉤新增至擴充功能,讓使用者在擴充功能將大寫訊息寫入即時資料庫之後,自行定義要執行的處理步驟。非同步掛鉤會使用 Eventarc 觸發使用者定義的函式。擴充功能會宣告其發出的事件類型,當使用者安裝擴充功能時,還會選擇感興趣的事件類型。如果他們選擇至少一個事件,Firebase 會在安裝過程中為擴充功能佈建 Eventarc 管道。使用者接著就能部署自己的雲端函式,用於監聽該管道,並在擴充功能發布新事件時觸發。

請按照下列步驟新增非同步掛鉤:

  1. extension.yaml 檔案中新增下列區段,以宣告擴充功能發出的一種事件類型:

    events:
      - type: test-publisher.rtdb-uppercase-messages.v1.complete
        description: >-
          Occurs when message uppercasing completes. The event subject will contain
          the RTDB URL of the uppercase message.
    

    事件類型必須完全不重複;為確保不重複,請一律使用以下格式為事件命名:<publisher-id>.<extension-id>.<version>.<description>。(您目前沒有發布商 ID,因此請暫時先使用 test-publisher)。

  2. makeuppercase 函式的結尾加入一些程式碼,用於發布您剛才宣告的類型事件:

    functions/index.js

    // Import the Eventarc library:
    import { initializeApp } from "firebase-admin/app";
    import { getEventarc } from "firebase-admin/eventarc";
    
    const app = initializeApp();
    
    // In makeuppercase, after upperRef.set(uppercase), add:
    
    // 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: "test-publisher.rtdb-uppercase-messages.v1.complete",
        subject: upperRef.toString(),
        data: {
          "original": original,
          "uppercase": uppercase,
        },
      });
    

    這個範例程式碼充分利用了 EVENTARC_CHANNEL 環境變數,只有在使用者啟用至少一個事件類型時才會定義。如果未定義 EVENTARC_CHANNEL,程式碼就不會嘗試發布任何事件。

    您可以在 Eventarc 事件中附加額外資訊。在上述範例中,事件的 subject 欄位包含新建立值的參照,以及包含原始訊息和大寫訊息的 data 酬載。而觸發事件的使用者定義函式可利用這項資訊。

  3. 一般來說,EVENTARC_CHANNELEXT_SELECTED_EVENTS 環境變數是根據在安裝期間選取的選項所定義。如要使用模擬器進行測試,請在 rtdb-uppercase-messages.env 檔案中手動定義這些變數:

    EVENTARC_CHANNEL=locations/us-central1/channels/firebase
    EXT_SELECTED_EVENTS=test-publisher.rtdb-uppercase-messages.v1.complete
    

此時,您已完成在擴充功能中新增非同步事件掛鉤的必要步驟。

如要試用您剛實作的新功能,請在接下來幾個步驟中以安裝擴充功能的使用者的角色假設:

  1. functions/integration-tests 目錄初始化新的 Firebase 專案:

    firebase init functions
    

    當系統提示時,請拒絕設定預設專案,將「JavaScript」選為 Cloud Functions 語言,然後安裝必要的依附元件。此專案代表了已安裝擴充功能的 user 專案。

  2. 編輯 integration-tests/functions/index.js 並貼上以下程式碼:

    import { logger } from "firebase-functions/v1";
    import { onCustomEventPublished } from "firebase-functions/v2/eventarc";
    
    import { initializeApp } from "firebase-admin/app";
    import { getDatabase } from "firebase-admin/database";
    
    const app = initializeApp();
    
    export const extraemphasis = onCustomEventPublished(
      "test-publisher.rtdb-uppercase-messages.v1.complete",
      async (event) => {
        logger.info("Received makeuppercase completed event", event);
    
        const refUrl = event.subject;
        const ref = getDatabase().refFromURL(refUrl);
        const upper = (await ref.get()).val();
        return ref.set(`${upper}!!!`);
      }
    );
    

    這是使用者可能會編寫的後處理函式範例。在此情況下,函式會監聽擴充功能以發布 complete 事件,並在觸發時,將三個驚嘆號加到新大寫的訊息中。

  3. 重新啟動模擬器。模擬器會載入擴充功能的函式,以及「user」定義的後處理函式。

  4. 前往資料庫模擬器 UI,使用您在上方定義的路徑編輯資料庫的根節點:

    • 欄位:msgs
    • 類型: json
    • 值: {"11": {"original": "recipe"}}

    儲存資料庫變更時,擴充功能的 makeuppercase 函式和使用者的 extraemphasis 函式應依序觸發,進而讓 upper 欄位取得 RECIPE!!! 值。

8. 新增生命週期事件處理常式

您到目前為止編寫的擴充功能會處理建立的訊息。但如果使用者安裝擴充功能時已有訊息資料庫,該怎麼辦?Firebase Extensions 提供一項名為生命週期事件掛鉤的功能,你可以在擴充功能安裝、更新或重新設定時觸發動作。在本節中,您將在使用者安裝擴充功能時,使用生命週期事件掛鉤,以大寫訊息補充專案現有的訊息資料庫。

Firebase Extensions 會透過 Cloud Tasks 執行生命週期事件處理常式。您可以利用 Cloud Functions 定義事件處理常式;每當您的擴充功能執行個體到達其中一個支援的生命週期事件時,如果您已定義處理常式,它就會將處理常式新增至 Cloud Tasks 佇列。接著,Cloud Tasks 會以非同步方式執行處理常式。生命週期事件處理常式執行時,Firebase 控制台會向使用者回報擴充功能執行個體有正在執行的處理工作。處理常式函式可把進行中狀態和工作完成回報回報給使用者。

如要新增可補充現有訊息的生命週期事件處理常式,請按照下列步驟操作:

  1. 定義由工作佇列事件觸發的新 Cloud 函式:

    functions/index.js

    import { tasks } from "firebase-functions/v1";
    
    import { getDatabase } from "firebase-admin/database";
    import { getExtensions } from "firebase-admin/extensions";
    import { getFunctions } from "firebase-admin/functions";
    
    export const backfilldata = tasks.taskQueue().onDispatch(async () => {
      const batch = await getDatabase()
        .ref(process.env.MESSAGE_PATH)
        .parent.parent.orderByChild("upper")
        .limitToFirst(20)
        .get();
    
      const promises = [];
      for (const key in batch.val()) {
        const msg = batch.child(key);
        if (msg.hasChild("original") && !msg.hasChild("upper")) {
          const upper = msg.child("original").val().toUpperCase();
          promises.push(msg.child("upper").ref.set(upper));
        }
      }
      await Promise.all(promises);
    
      if (promises.length > 0) {
        const queue = getFunctions().taskQueue(
          "backfilldata",
          process.env.EXT_INSTANCE_ID
        );
        return queue.enqueue({});
      } else {
        return getExtensions()
          .runtime()
          .setProcessingState("PROCESSING_COMPLETE", "Backfill complete.");
      }
    });
    

    請注意,函式只會處理一些記錄,之後才將本身加回工作佇列。這個常用策略來處理無法在 Cloud 函式逾時期限內完成的處理工作。由於您無法預測使用者安裝擴充功能時,資料庫中可能已擁有多少訊息,因此這項策略相當適合。

  2. extension.yaml 檔案中,將補充函式宣告為具有 taskQueueTrigger 屬性的擴充功能資源:

    resources:
      - name: makeuppercase
        ...
      - name: backfilldata
        type: firebaseextensions.v1beta.function
        description: >-
          Backfill existing messages with uppercase versions
        properties:
          runtime: "nodejs18"
          taskQueueTrigger: {}
    

    然後將函式宣告為 onInstall 生命週期事件的處理常式:

    lifecycleEvents:
      onInstall:
        function: backfilldata
        processingMessage: Uppercasing existing messages
    
  3. 雖然可以補充現有訊息是不錯的做法,但擴充功能在沒有該訊息的情況下仍可正常運作。在這種情況下,您應選擇執行生命週期事件處理常式。

    方法是在 extension.yaml 中新增參數:

    - param: DO_BACKFILL
      label: Backfill existing messages
      description: >-
        Generate uppercase versions of existing messages?
      type: select
      required: true
      options:
        - label: Yes
          value: true
        - label: No
          value: false
    

    接著,在補充函式的開頭檢查 DO_BACKFILL 參數的值,如未設定,請提早結束:

    functions/index.js

    if (!process.env.DO_BACKFILL) {
      return getExtensions()
        .runtime()
        .setProcessingState("PROCESSING_COMPLETE", "Backfill skipped.");
    }
    

完成上述變更後,擴充功能會在安裝時將現有訊息轉換成大寫。

到目前為止,您已使用擴充功能模擬器開發擴充功能,並測試持續進行的變更。不過,擴充功能模擬器會略過安裝程序,因此如要測試 onInstall 事件處理常式,您必須在實際專案中安裝擴充功能。也同樣是,由於加入了這項自動補充功能,教學課程擴充功能現在已經完成程式碼!

9. 部署至實際的 Firebase 專案

雖然擴充功能模擬器非常適合在開發期間快速疊代擴充功能,但您可能會在某個時間點嘗試在實際專案中試用。

如要這麼做,請先設定新專案並啟用部分服務:

  1. Firebase 主控台中新增專案。
  2. 將專案升級為即付即用的 Blaze 方案。您必須有帳單帳戶,才能使用 Cloud Functions for Firebase 安裝擴充功能。
  3. 在新專案中,啟用即時資料庫
  4. 由於您想測試擴充功能在安裝時補充現有資料的能力,因此請將一些範例資料匯入即時資料庫執行個體:
    1. 下載一些 種子 RTDB 資料
    2. 在 Firebase 控制台的「Realtime Database」(即時資料庫) 頁面中,依序按一下 (更多) >「Import JSON」(匯入 JSON),然後選取您剛才下載的檔案。
  5. 如要讓補充函式使用 orderByChild 方法,請設定資料庫,根據 upper 的值建立訊息索引:

    {
      "rules": {
        ".read": false,
        ".write": false,
        "messages": {
          ".indexOn": "upper"
        }
      }
    }
    

接著,從本機來源將擴充功能安裝到新專案中:

  1. 為 Firebase 專案建立新目錄:

    mkdir ~/extensions-live-test && cd ~/extensions-live-test
    
  2. 初始化工作目錄中的 Firebase 專案:

    firebase init database
    

    系統提示時,請選取您剛剛建立的專案。

  3. 將擴充功能安裝在本機 Firebase 專案中:

    firebase ext:install /path/to/rtdb-uppercase-messages
    

    透過 Firebase CLI 工具,您可以在安裝擴充功能時瞭解使用者體驗。當設定工具詢問是否要為現有資料庫進行補充作業時,請務必選取「是」。

    選取設定選項後,Firebase CLI 會將您的設定儲存在 extensions 目錄中,並在 firebase.json 檔案中記錄擴充功能來源位置。以上兩筆記錄一起稱為「擴充功能資訊清單」。使用者可以使用資訊清單來儲存擴充功能設定,並部署至不同的專案。

  4. 將擴充功能設定部署至進行中的專案:

    firebase deploy --only extensions
    

如果一切順利,Firebase CLI 應將擴充功能上傳至專案並安裝。安裝完成後,補充作業工作會執行,並在幾分鐘後以大寫訊息更新資料庫。請將一些新的節點新增至訊息資料庫,並確認擴充功能也可以正常接收新訊息。

10. 撰寫說明文件

與使用者分享擴充功能前,請務必提供足夠文件,讓使用者能順利完成工作。

初始化擴充功能專案時,Firebase CLI 會建立最低必要說明文件的虛設常式版本。請更新這些檔案,準確反映建構的擴充功能。

擴充功能.yaml

在您開發此擴充功能的同時,這個檔案已經更新,因此目前不需要再進行任何更新。

不過,請您不要忽略這個檔案中說明文件的重要性。除了擴充功能的重要識別資訊 (名稱、說明、作者、官方存放區位置) 以外,extension.yaml 檔案也包含向使用者顯示的每個資源和可設定參數的說明文件。這項資訊會顯示在 Firebase 控制台、Extensions Hub 和 Firebase CLI 中。

PREINSTALL.md

在這個檔案中,在使用者安裝擴充功能前提供必要資訊:簡要說明擴充功能的功能、說明任何必要條件,並向使用者提供安裝擴充功能對帳單的影響。如果您有網站可以提供額外資訊,也可以在這裡連結。

使用者會在擴充功能中心和 firebase ext:info 指令中看到這個檔案的文字。

以下是 PREINSTALL 檔案的範例:

Use this extension to automatically convert strings to upper case when added to
a specified Realtime Database path.

This extension expects a database layout like the following example:

    "messages": {
      MESSAGE_ID: {
        "original": MESSAGE_TEXT
      },
      MESSAGE_ID: {
        "original": MESSAGE_TEXT
      },
    }

When you create new string records, this extension creates a new sibling record
with upper-cased text:

    MESSAGE_ID: {
      "original": MESSAGE_TEXT,
      "upper": UPPERCASE_MESSAGE_TEXT,
    }

#### Additional setup

Before installing this extension, make sure that you've
[set up Realtime Database](https://firebase.google.com/docs/database/quickstart)
in your Firebase project.

#### Billing

To install an extension, your project must be on the
[Blaze (pay as you go) plan](https://firebase.google.com/pricing).

- This extension uses other Firebase and Google Cloud Platform services, which
  have associated charges if you exceed the service's no-cost tier:
  - Realtime Database
  - Cloud Functions (Node.js 10+ runtime)
    [See FAQs](https://firebase.google.com/support/faq#extensions-pricing)
- If you enable events,
  [Eventarc fees apply](https://cloud.google.com/eventarc/pricing).

POSTINSTALL.md

使用者成功安裝擴充功能後,這個檔案的內容會相當實用,例如後續設定步驟、擴充功能的實際操作範例等。

設定並安裝擴充功能後,POSTINSTALL.md 的內容會顯示在 Firebase 控制台中。您可以參照這個檔案中的使用者參數,這些參數會由設定的值取代。

以下是教學課程擴充功能的安裝後檔案範例:

### See it in action

You can test out this extension right away!

1.  Go to your
    [Realtime Database dashboard](https://console.firebase.google.com/project/${param:PROJECT_ID}/database/${param:PROJECT_ID}/data) in the Firebase console.

1.  Add a message string to a path that matches the pattern `${param:MESSAGE_PATH}`.

1.  In a few seconds, you'll see a sibling node named `upper` that contains the
    message in upper case.

### Using the extension

We recommend adding data by pushing -- for example,
`firebase.database().ref().push()` -- because pushing assigns an automatically
generated ID to the node in the database. During retrieval, these nodes are
guaranteed to be ordered by the time they were added. Learn more about reading
and writing data for your platform (iOS, Android, or Web) in the
[Realtime Database documentation](https://firebase.google.com/docs/database/).

### Monitoring

As a best practice, you can
[monitor the activity](https://firebase.google.com/docs/extensions/manage-installed-extensions#monitor)
of your installed extension, including checks on its health, usage, and logs.

CHANGELOG.md

您在 CHANGELOG.md 檔案中擴充功能發布之間的變更,也應記錄下來。

由於範例擴充功能先前從未發布,變更記錄只會有一個項目:

## Version 0.0.1

Initial release of the _Convert messages to upper case_ extension.

README.md

大多數擴充功能也會提供 README 檔案,以便造訪擴充功能存放區的使用者瞭解相關資訊。您可以使用指令手動編寫這個檔案,或是產生「Read me」(讀我) 檔案。

為達到本指南的目的,請略過撰寫 Readme 檔案的說明。

其他說明文件

上述說明文件是您應為使用者提供的基本說明文件集。許多擴充功能需要更詳盡的說明文件,才能讓使用者成功運用。如果是這種情況,建議您撰寫其他說明文件,並代管能將使用者導向至何處。

為達到本指南的目的,請略過撰寫更詳盡的說明文件。

11. 發布到 Extensions Hub

擴充功能現已完整編寫並記錄完畢,您現在可以在 Extensions Hub 上與全世界分享。不過,由於教學課程只是教學,因此請勿這麼做。您可以參考本文和 Firebase Extensions 發布商說明文件,開始編寫自己的擴充功能,並檢查 Firebase 編寫的官方擴充功能來源。

準備好在 Extensions Hub 上發布作品時,請按照下列步驟操作:

  1. 如果要發布第一個擴充功能,請註冊為擴充功能發布者。註冊成為擴充功能發布者時,系統會建立發布者 ID,讓使用者快速識別你是擴充功能的作者。
  2. 將擴充功能的原始碼存放在可公開驗證的位置。如果可從可驗證的來源取得程式碼,Firebase 就能直接從這個位置發布您的擴充功能。這有助於確保您發布的擴充功能是目前發布的版本,並讓使用者得以檢查要在專案中安裝的程式碼。

    目前,這表示在公開的 GitHub 存放區中提供您的擴充功能。

  3. 使用 firebase ext:dev:upload 指令將擴充功能上傳至 Extensions Hub。

  4. 前往 Firebase 控制台的發布者資訊主頁,找到剛剛上傳的擴充功能,然後按一下「Publish to Extensions Hub」。要求審查人員會要求審查,但可能需要幾天的時間才能完成。擴充功能獲得核准後,就會發布到擴充功能中心。如果遭拒,您會收到說明原因的訊息,接著可以處理回報的問題並重新送審。