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


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

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

這是包含函數的完整範例程式碼:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

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

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = 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 getFirestore()
      .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 saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

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

  const uppercase = original.toUpperCase();

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

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

關於本教程

我們為此範例選擇了 Cloud Firestore 和 HTTP 觸發的函數,部分原因是這些後台觸發器可以透過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 專案的概述頁面。

設定您的環境和 Firebase CLI

Node.js

您需要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 ,請重新執行相同的指令。

Python

您需要Python環境來編寫函數,並且需要 Firebase CLI 將函數部署到 Cloud Functions 執行時間。我們建議使用venv來隔離依賴關係。支援 Python 版本 3.10 和 3.11。

安裝 Python 後,透過您首選的方法安裝 Firebase CLI

初始化您的項目

初始化 Firebase SDK for Cloud Functions 時,您將建立一個包含依賴項和一些最少範例程式碼的空專案。如果您使用 Node.js,則可以選擇 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
    • 打字稿
    • Python

    對於本教學課程,選擇JavaScriptPython 。有關使用 TypeScript 進行創作的信息,請參閱使用 TypeScript 編寫函數

  6. CLI 為您提供了安裝依賴項的選項。如果您想以其他方式管理依賴項,可以安全地拒絕。

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

Node.js

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

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

Python

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
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

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

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

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

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

initializeApp();

Python

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

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

當您初始化專案時,Firebase CLI 會自動安裝 Firebase Admin SDK 和 Firebase SDK for Cloud Functions 模組。有關將第 3 方庫新增至專案的更多信息,請參閱處理依賴項

新增「新增訊息」功能

對於「新增訊息」功能,請將這些行新增至來源檔案:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = 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 getFirestore()
      .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.`});
});

Python

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")

「新增訊息」功能是一個 HTTP 端點。對端點的任何請求都會導致請求和回應物件傳遞到您平台的請求處理程序( onRequest()on_request )。

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

新增“變為大寫”功能

對於“make uppercase”函數,請將這些行加入到原始檔中:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

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

  const uppercase = original.toUpperCase();

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

Python

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

「make uppercase」函數在寫入 Cloud Firestore 時執行,定義要偵聽的文件。出於性能原因,您應該盡可能具體。

大括號(例如, {documentId}包圍「參數」和通配符,這些通配符在回呼中公開其匹配的資料。每當新增訊息時,Cloud Firestore 就會觸發回呼。

在 Node.js 中,事件驅動函數(例如 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 函數的 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. 「日誌」標籤中,您應該會看到新日誌,表示您的 HTTP 函數已成功運行:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

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

將功能部署到生產環境

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

要完成本教程,請部署您的函數,然後執行它們。

  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 輸出的 URL,新增文字查詢參數,然後在瀏覽器中開啟它:

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

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

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

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

下一步

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

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