了解 2023 年 Google I/O 大会上介绍的 Firebase 亮点。了解详情

管理功能


您可以使用 Firebase CLI 命令或通過在函數源代碼中設置運行時選項來部署、刪除和修改函數。

部署功能

要部署函數,請運行此 Firebase CLI 命令:

firebase deploy --only functions

默認情況下,Firebase CLI 會同時在您的源代碼中部署所有函數。如果您的項目包含超過 5 個函數,我們建議您使用帶有特定函數名稱的--only標誌以僅部署您編輯的函數。以這種方式部署特定功能可加快部署過程並幫助您避免達到部署配額。例如:

firebase deploy --only functions:addMessage,functions:makeUppercase

部署大量函數時,您可能會超出標準配額並收到 HTTP 429 或 500 錯誤消息。要解決此問題,請以 10 個或更少為一組部署功能。

有關可用命令的完整列表,請參閱Firebase CLI 參考

默認情況下,Firebase CLI 在functions/文件夾中查找源代碼。如果願意,您可以在代碼庫或多組文件中組織函數

刪除功能

您可以通過以下方式刪除之前部署的函數:

  • 明確地在 Firebase CLI 中使用functions:delete
  • 明確地谷歌云控制台中。
  • 通過在部署之前從源中刪除函數來隱式地

在從生產中刪除功能之前,所有刪除操作都會提示您確認。

Firebase CLI 中的顯式函數刪除支持多個參數和函數組,並允許您指定在特定區域中運行的函數。此外,您可以覆蓋確認提示。

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

通過隱式函數刪除, firebase deploy解析您的源代碼並從生產中刪除任何已從文件中刪除的函數。

修改函數的名稱、區域或觸發器

如果您要重命名或更改處理生產流量的函數的區域或觸發器,請按照本節中的步驟操作以避免在修改期間丟失事件。在執行這些步驟之前,首先確保您的函數是冪等的,因為在更改期間,您的函數的新版本和舊版本將同時運行。

重命名函數

要重命名函數,請在您的源中創建函數的新重命名版本,然後運行兩個單獨的部署命令。第一個命令部署新命名的函數,第二個命令刪除以前部署的版本。例如,如果您有一個名為webhook的 Node.js 函數,您想要更改為webhookNew ,請按如下方式修改代碼:

// before
const functions = require('firebase-functions');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

然後運行以下命令來部署新功能:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

更改一個或多個函數的區域

如果您要更改處理生產流量的函數的指定區域,則可以通過按順序執行以下步驟來防止事件丟失:

  1. 重命名函數,並根據需要更改其區域。
  2. 部署重命名的函數,這會導致在兩組區域中臨時運行相同的代碼。
  3. 刪除之前的功能。

例如,如果您有一個名為webhook的函數當前位於us-central1的默認函數區域,並且您想將其遷移到asia-northeast1 ,則需要先修改源代碼以重命名該函數並修改區域.

// before
const functions = require('firebase-functions');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

然後通過運行部署:

firebase deploy --only functions:webhookAsia

現在有兩個相同的函數在運行: webhookus-central1中運行, webhookAsiaasia-northeast1中運行。

然後,刪除webhook

firebase functions:delete webhook

現在只有一個函數 - webhookAsia ,它在asia-northeast1中運行。

更改函數的觸發器類型

隨著時間的推移開發 Cloud Functions for Firebase 部署,您可能需要出於各種原因更改函數的觸發器類型。例如,您可能希望將一種類型的 Firebase 實時數據庫或 Cloud Firestore 事件更改為另一種類型。

僅通過更改源代碼和運行firebase deploy是不可能更改函數的事件類型的。為避免錯誤,請通過以下過程更改函數的觸發器類型:

  1. 修改源代碼以包含具有所需觸發器類型的新函數。
  2. 部署函數,這會導致臨時運行舊函數和新函數。
  3. 使用 Firebase CLI 從生產中明確刪除舊函數。

例如,如果您有一個名為objectChanged的​​ Node.js 函數,它具有舊的onChange事件類型,並且您想將其更改為onFinalize ,請先重命名該函數並將其編輯為具有onFinalize事件類型。

// before
const functions = require('firebase-functions');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

然後運行以下命令先創建新函數,然後再刪除舊函數:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

設置運行時選項

Cloud Functions for Firebase 允許您選擇運行時選項,例如 Node.js 運行時版本和每個函數的超時、內存分配和最小/最大函數實例。

作為最佳實踐,應在函數代碼內的配置對像上設置這些選項(Node.js 版本除外)。此RuntimeOptions對像是函數運行時選項的真實來源,並將覆蓋通過任何其他方法(例如通過 Google Cloud 控制台或 gcloud CLI)設置的選項。

如果您的開發工作流程涉及通過 Google Cloud 控制台或 gcloud CLI 手動設置運行時選項,並且您希望在每次部署時覆蓋這些值,請將preserveExternalChanges選項設置為true 。將此選項設置為true後,Firebase 會將代碼中設置的運行時選項與當前部署的函數版本的設置合併,優先級如下:

  1. 選項在功能代碼中設置:覆蓋外部更改。
  2. 選項在函數代碼中設置為RESET_VALUE :使用默認值覆蓋外部更改。
  3. 選項未在函數代碼中設置,但在當前部署的函數中設置:使用已部署函數中指定的選項。

在大多數情況下,不建議使用preserveExternalChanges: true選項,因為您的代碼將不再是函數運行時選項的完整真實來源。如果確實要使用它,請檢查 Google Cloud 控制台或使用 gcloud CLI 查看函數的完整配置。

設置 Node.js 版本

Firebase SDK for Cloud Functions 2.0.0 及更高版本允許選擇 Node.js 運行時。您可以選擇在與這些受支持的 Node.js 版本之一相對應的運行時環境中專門運行項目中的所有功能:

  • Node.js 20 (預覽版)
  • 節點 18
  • 節點 16
  • 節點 14

要設置 Node.js 版本:

在初始化期間在您的functions/目錄中創建的package.json文件中的engines字段中設置版本。例如,要僅使用版本 18,請在package.json中編輯此行:

  "engines": {"node": "18"}

engines字段是必需的;它必須指定受支持的 Node.js 版本之一,以便您部署和運行功能。

升級您的 Node.js 運行時

要升級您的 Node.js 運行時:

  1. 確保您的項目在Blaze 定價計劃中。
  2. 確保您使用的是 Firebase CLI v11.18.0 或更高版本。
  3. 更改初始化期間在functions/目錄中創建的package.json文件中的engines值。例如,如果您要從版本 16 升級到版本 18,條目應如下所示: "engines": {"node": "18"}
  4. 或者,使用Firebase Local Emulator Suite測試您的更改。
  5. 重新部署所有功能。

控制縮放行為

默認情況下,Cloud Functions for Firebase 根據傳入請求的數量縮放正在運行的實例的數量,並可能在流量減少時縮減為零個實例。但是,如果您的應用程序需要減少延遲並且您想要限製冷啟動的次數,您可以通過指定最小數量的容器實例來保持溫暖並準備好為請求服務來更改此默認行為。

同樣,您可以設置最大數量來限制實例響應傳入請求的擴展。使用此設置來控製成本或限制與支持服務(例如數據庫)的連接數。

減少冷啟動次數

要在源代碼中設置函數的最小實例數,請使用runWith方法。此方法接受符合RuntimeOptions接口的 JSON 對象,該接口定義了minInstances的值。例如,此函數設置至少 5 個實例來保暖:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

以下是為minInstances設置值時需要考慮的一些事項:

  • 如果 Cloud Functions for Firebase 將您的應用程序擴展到您的minInstances設置之上,您將遇到超過該閾值的每個實例的冷啟動。
  • 冷啟動對流量激增的應用程序影響最為嚴重。如果您的應用程序流量激增,並且您將minInstances值設置得足夠高,每次流量增加時冷啟動都會減少,您將看到延遲顯著減少。對於流量恆定的應用程序,冷啟動不太可能嚴重影響性能。
  • 設置最小實例對於生產環境是有意義的,但在測試環境中通常應該避免。要在測試項目中縮放到零但仍減少生產項目中的冷啟動,您可以根據FIREBASE_CONFIG環境變量設置minInstances

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

限制函數的最大實例數

要在函數源代碼中設置最大實例數,請使用runWith方法。此方法接受符合RuntimeOptions接口的 JSON 對象,該接口定義了maxInstances的值。例如,此函數設置 100 個實例的限制,以免淹沒假設的遺留數據庫:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

如果 HTTP 函數擴展到maxInstances限制,新請求將排隊 30 秒,然後在沒有可用實例的情況下以429 Too Many Requests的響應代碼拒絕。

要了解有關使用最大實例設置的最佳實踐的更多信息,請查看這些使用maxInstances最佳實踐

設置超時和內存分配

在某些情況下,您的函數可能對長超時值或大量內存分配有特殊要求。您可以在 Google Cloud Console 或函數源代碼(僅限 Firebase)中設置這些值。

要在函數源代碼中設置內存分配和超時,請使用 Firebase SDK for Cloud Functions 2.0.0 中引入的runWith參數。此運行時選項接受符合RuntimeOptions接口的 JSON 對象,該接口定義了timeoutSecondsmemory的值。例如,此存儲函數使用 1GB 內存並在 300 秒後超時:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

timeoutSeconds的最大值為540或 9 分鐘。授予函數的內存量對應於為該函數分配的 CPU,如以下memory有效值列表中的詳細信息:

  • 128MB — 200MHz
  • 256MB — 400MHz
  • 512MB — 800MHz
  • 1GB — 1.4 GHz
  • 2GB — 2.4 GHz
  • 4GB — 4.8 GHz
  • 8GB — 4.8 GHz

要在 Google Cloud Console 中設置內存分配和超時:

  1. 在 Google Cloud Console 中,從左側菜單中選擇Cloud Functions
  2. 通過在函數列表中單擊函數名稱來選擇函數。
  3. 單擊頂部菜單中的編輯圖標。
  4. 從標記為Memory allocated的下拉菜單中選擇一個內存分配。
  5. 單擊更多以顯示高級選項,並在超時文本框中輸入秒數。
  6. 單擊保存以更新函數。