開始:編寫、測試和部署您的第一個函數


要開始使用 Cloud Functions,請嘗試完成本教學課程,該教學從所需的設定任務開始,然後透過建立、測試和部署兩個相關函數:

  • 「新增訊息」函數,公開接受文字值並將其寫入 Cloud Firestore 的 URL。
  • 在 Cloud Firestore 寫入時觸發的「變成大寫」函數,並將文字轉換為大寫。

我們為此範例選擇了 Cloud Firestore 和 HTTP 觸發的 JavaScript 函數,部分原因是這些後台觸發器可以透過Firebase 本機模擬器套件進行徹底測試。該工具集還支援即時資料庫、PubSub、Auth 和 HTTP 可呼叫觸發器。其他類型的後台觸發器(例如遠端設定、TestLab 和分析觸發器)都可以使用本頁中未描述的工具集進行互動測試

本教學的以下部分詳細介紹了建置、測試和部署範例所需的步驟。如果您只想運行程式碼並檢查它,請跳到查看完整的範例程式碼

創建 Firebase 項目

  1. Firebase 控制台中,按一下新增項目

    • 若要將 Firebase 資源新增至現有Google Cloud 項目,請輸入其項目名稱或從下拉式選單中選擇。

    • 若要建立新項目,請輸入所需的項目名稱。您也可以選擇編輯項目名稱下方顯示的項目 ID。

  2. 如果出現提示,請查看並接受Firebase 條款

  3. 單擊繼續

  4. (可選)為您的專案設定 Google Analytics,這使您能夠使用以下任何 Firebase 產品獲得最佳體驗:

    選擇現有的Google Analytics 帳戶或建立新帳戶。

    如果您建立新帳戶,請選擇您的Analytics 報告位置,然後接受項目的資料共享設定和 Google Analytics 條款。

  5. 點擊建立項目(如果您使用的是現有 Google Cloud 項目,請點擊 新增 Firebase )。

Firebase 會自動為您的 Firebase 專案設定資源。過程完成後,您將進入 Firebase 控制台中 Firebase 專案的概述頁面。

設定 Node.js 和 Firebase CLI

您需要Node.js環境來編寫函數,並且需要 Firebase CLI 將函數部署到 Cloud Functions 執行時間。若要安裝 Node.js 和npm ,建議使用Node Version Manager

安裝 Node.js 和 npm 後,透過您首選的方法安裝 Firebase CLI 。若要透過 npm 安裝 CLI,請使用:

npm install -g firebase-tools

這將安裝全域可用的 firebase 命令。如果命令失敗,您可能需要變更 npm 權限。若要更新至最新版本的firebase-tools ,請重新執行相同的指令。

初始化您的項目

初始化 Firebase SDK for Cloud Functions 時,您將建立一個包含依賴項和一些最少範例程式碼的空項目,並選擇 TypeScript 或 JavaScript 來編寫函數。出於本教學的目的,您還需要初始化 Cloud Firestore。

要初始化您的專案:

  1. 運行firebase login以透過瀏覽器登入並對 Firebase CLI 進行身份驗證。
  2. 前往您的 Firebase 專案目錄。
  3. 運行firebase init firestore 。對於本教學課程,當提示輸入 Firestore 規則和索引檔案時,您可以接受預設值。如果您尚未在此專案中使用 Cloud Firestore,則您還需要選擇 Firestore 的啟動模式和位置​​,如Cloud Firestore 入門中所述。
  4. 運行firebase init functions 。 CLI 會提示您選擇現有程式碼庫或初始化並命名新程式碼庫。當您剛開始時,預設位置中的單一程式碼庫就足夠了;稍後,隨著您的實現的擴展,您可能希望在程式碼庫中組織函數
  5. CLI 為您提供了兩種語言支援選項:

    對於本教學課程,選擇JavaScript

  6. CLI 為您提供了使用 npm 安裝依賴項的選項。如果您想以其他方式管理依賴項,可以安全地拒絕,但如果您確實拒絕,則需要在模擬或部署功能之前執行npm install

這些命令成功完成後,您的專案結構如下所示:

myproject
 +- .firebaserc    # Hidden file that helps you quickly switch between
 |                 # projects with `firebase use`
 |
 +- firebase.json  # Describes properties for your project
 |
 +- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # main source file for your Cloud Functions code
      |
      +- node_modules/ # directory where your dependencies (declared in
                       # package.json) are installed

初始化期間建立的package.json檔案包含一個重要的按鍵: "engines": {"node": "16"} 。這指定了用於編寫和部署函數的 Node.js 版本。您可以選擇其他支援的版本

導入所需的模組並初始化應用程式

完成設定任務後,您可以開啟來源目錄並開始新增程式碼,如以下部分所述。對於此範例,您的專案必須使用 Node require語句導入 Cloud Functions 和 Admin SDK 模組。將如下行新增至您的index.js檔案:

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

這些行會載入firebase-functionsfirebase-admin模組,並初始化可以從中進行 Cloud Firestore 變更的admin應用實例。只要提供Admin SDK支持,例如 FCM、身份驗證和 Firebase 即時資料庫,它就提供了一種使用 Cloud Functions 整合 Firebase 的強大方法。

當您初始化專案時,Firebase CLI 會自動安裝 Firebase 和 Firebase SDK for Cloud Functions Node 模組。若要將第 3 方庫新增至您的專案中,您可以修改package.json並執行npm install 。有關更多信息,請參閱處理依賴關係

新增addMessage()函數

對於addMessage()函數,請將以下行加入index.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await admin
    .firestore()
    .collection("messages")
    .add({ original: original });
  // Send back a message that we've successfully written the message
  res.json({ result: `Message with ID: ${writeResult.id} added.` });
});

addMessage()函數是一個 HTTP 端點。對端點的任何請求都會產生傳遞給onRequest()回呼的 ExpressJS 樣式的RequestResponse物件。

HTTP 函數是同步的(類似於可呼叫函數),因此您應該盡快發送回應並使用 Cloud Firestore 推遲工作。 addMessage() HTTP 函數將文字值傳遞到 HTTP 端點,並將其插入路徑/messages/:documentId/original下的資料庫中。

新增makeUppercase()函數

對於makeUppercase()函數,請將以下行加入index.js

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

makeUppercase()函數在寫入 Cloud Firestore 時執行。 ref.set函數定義要監聽的文件。出於性能原因,您應該盡可能具體。

大括號(例如, {documentId}包圍「參數」和通配符,這些通配符在回呼中公開其匹配的資料。

每當新增訊息時,Cloud Firestore 都會觸發onCreate()回呼。

Cloud Firestore 事件等事件驅動功能是非同步的。回呼函數應該回傳null 、 Object 或Promise 。如果您不回傳任何內容,函數就會逾時,發出錯誤訊號,然後重試。請參閱同步、非同步和 Promise

模擬函數的執行

Firebase 本機模擬器套件可讓您在本機電腦上建置和測試應用程序,而不是部署到 Firebase 專案。強烈建議在開發期間進行本地測試,部分原因是它可以降低編碼錯誤的風險,而編碼錯誤可能會在生產環境中產生成本(例如,無限循環)。

要模擬您的功能:

  1. 執行firebase emulators:start並檢查 Emulator Suite UI URL 的輸出。它預設為localhost:4000 ,但可能託管在您電腦上的不同連接埠上。在瀏覽器中輸入該 URL 以開啟模擬器套件 UI。

  2. 檢查firebase emulators:start指令的輸出,了解 HTTP 函式addMessage()的 URL。它看起來類似http://localhost:5001/MY_PROJECT/us-central1/addMessage ,除了:

    1. MY_PROJECT將替換為您的項目 ID。
    2. 您本機電腦上的連接埠可能不同。
  3. 將查詢字串?text=uppercaseme加入到函數 URL 的末尾。這應該類似於: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme 。或者,您可以將訊息“uppercaseme”變更為自訂訊息。

  4. 透過在瀏覽器的新分頁中開啟 URL 來建立新訊息。

  5. 查看Emulator Suite UI中各功能的效果:

    1. 「日誌」標籤中,您應該會看到新日誌,表示函數addMessage()makeUppercase()運行:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. Firestore選項卡中,您應該會看到一個包含原始訊息以及訊息的大寫版本的文件(如果它最初是“uppercaseme”,您將看到“UPPERCASEME”)。

將功能部署到生產環境

一旦您的函數在模擬器中按預期工作,您就可以繼續在生產環境中部署、測試和運行它們。請記住,要部署到建議的 Node.js 14 執行階段環境,您的專案必須採用Blaze 定價方案。請參閱雲端函數定價

要完成本教學課程,請部署您的函數,然後執行addMessage()以觸發makeUppercase()

  1. 執行以下命令來部署您的功能:

     firebase deploy --only functions
     

    執行此指令後,Firebase CLI 會輸出任何 HTTP 函數端點的 URL。在您的終端機中,您應該看到如下所示的一行:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    URL 包含您的專案 ID 以及 HTTP 函數的區域。雖然您現在不需要擔心,但某些生產 HTTP 函數應該指定一個位置以最大限度地減少網路延遲。

    如果您遇到存取錯誤,例如“無法授權存取項目”,請嘗試檢查您的專案別名

  2. 使用 CLI 輸出的addMessage() URL,新增文字查詢參數,然後在瀏覽器中開啟它:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    該函數執行並將瀏覽器重定向到儲存文字字串的資料庫位置處的 Firebase 控制台。此寫入事件會觸發makeUppercase() ,函數會寫入字串的大寫版本。

部署並執行功能後,您可以在Google Cloud 控制台中查看日誌。如果您需要刪除開發或生產中的函數,請使用 Firebase CLI。

在生產中,您可能希望透過設定要運行的最小和最大實例數來優化函數效能並控製成本。有關這些運行時選項的更多信息,請參閱控制縮放行為

查看完整的範例程式碼

這是已完成的functions/index.js其中包含函數addMessage()makeUppercase() 。這些函數可讓您將參數傳遞到 HTTP 端點,該端點將值寫入 Cloud Firestore,然後透過將字串中的所有字元大寫來轉換該值。

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await admin
    .firestore()
    .collection("messages")
    .add({ original: original });
  // Send back a message that we've successfully written the message
  res.json({ result: `Message with ID: ${writeResult.id} added.` });
});

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

    // Access the parameter `{documentId}` with `context.params`
    functions.logger.log("Uppercasing", context.params.documentId, original);

    const uppercase = original.toUpperCase();

    // You must return a Promise when performing asynchronous tasks inside a Functions such as
    // writing to Firestore.
    // Setting an 'uppercase' field in Firestore document returns a Promise.
    return snap.ref.set({ uppercase }, { merge: true });
  });

下一步

在本文檔中,您可以詳細了解如何管理 Cloud Functions 的函數以及如何處理 Cloud Functions 支援的所有事件類型。

要了解有關雲函數的更多信息,您還可以執行以下操作: