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


要開始使用 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 Console中查看日誌。如果您需要刪除開發或生產中的函數,請使用 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 支持的所有事件類型。

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