管理函式


如要部署、刪除及修改函式,您可以使用 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 明確提出
  • 明確用於 Google Cloud 控制台
  • 默示

所有刪除作業都會提示您進行確認,然後再將函式從實際工作環境中移除。

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 會剖析來源,並從實際工作環境中移除所有已從檔案中移除的函式。

修改函式的名稱、區域或觸發條件

如果您要重新命名或變更區域或觸發條件,以處理處理實際工作環境流量的函式,請按照本節的步驟操作,以免在修改期間遺失事件。在執行這些步驟前,請先確認您的函式為「冪等」,因為新版本和舊版函式會在變更期間同時執行。

重新命名函式

如要重新命名函式,請在來源中建立新的函式經過重新命名版本,然後執行兩個獨立的部署指令。第一個指令會部署新命名的函式,第二個指令則會移除先前部署的版本。舉例來說,如果您想為某個由 HTTP 觸發的 Webhook 重新命名,請修改程式碼,如下所示:

Node.js

// before
const {onRequest}  = require('firebase-functions/v2/https');

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

// after
const {onRequest}  = require('firebase-functions/v2/https');

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

Python

# before
from firebase_functions import https_fn

@https_fn.on_request()
def webhook(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

# after
from firebase_functions import https_fn

@https_fn.on_request()
def webhook_new(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

接著執行下列指令,部署新函式:

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

# Wait until deployment is done; now both functions are running

# Delete webhook
firebase functions:delete webhook

變更函式的區域或區域

如果您要為處理實際工作環境流量的函式變更指定地區,可以依序執行下列步驟,避免事件遺失:

  1. 重新命名函式,並視需要變更區域或區域。
  2. 部署重新命名的函式,以便在兩組區域中暫時執行相同的程式碼。
  3. 刪除前一個函式。

舉例來說,假設您有一個 Cloud Firestore 觸發的函式目前位於 us-central1 的預設函式地區,而您想將其遷移至 asia-northeast1,則必須先修改原始碼,將函式重新命名並修改區域。

Node.js

// before
exports.firestoreTrigger = onDocumentCreated(
  "my-collection/{docId}",
  (event) => {},
);

// after
exports.firestoreTriggerAsia = onDocumentCreated(
  {
    document: "my-collection/{docId}",
    region: "asia-northeast1",
  },
  (event) => {},
);

新版程式碼應指定正確的事件篩選器 (在本例中為 document) 和地區。詳情請參閱 Cloud Functions 位置

Python

# Before
@firestore_fn.on_document_created("my-collection/{docId}")
def firestore_trigger(event):
    pass

# After
@firestore_fn.on_document_created("my-collection/{docId}",
                                  region="asia-northeast1")
def firestore_trigger_asia(event):
    pass

接著執行下列指令來部署:

firebase deploy --only functions:firestoreTriggerAsia

現在有兩個相同的函式正在執行:firestoreTriggerus-central1 中執行,而 firestoreTriggerAsia 是在 asia-northeast1 中執行。

然後刪除 firestoreTrigger

firebase functions:delete firestoreTrigger

現在只有一個函式 - firestoreTriggerAsia,且在 asia-northeast1 中執行。

變更函式的觸發條件類型

隨著時間開發 Cloud Functions for Firebase 的部署作業時,您可能需要基於各種原因變更函式的觸發條件類型。舉例來說,您可能會想要從 Firebase 即時資料庫或 Cloud Firestore 事件類型變更為另一種類型。

您無法僅透過變更原始碼並執行 firebase deploy 來變更函式的事件類型。為避免發生錯誤,請透過下列方式變更函式的觸發條件類型:

  1. 修改原始碼,加入包含所需觸發條件類型的新函式。
  2. 部署函式,會導致新舊函式暫時同時執行。
  3. 使用 Firebase CLI 將舊函式從實際工作環境中刪除。

舉例來說,如果您的函式是在物件刪除時觸發,但之後您啟用了物件版本管理功能,並想改為訂閱封存事件,請先重新命名函式,並編輯函式,使其使用新的觸發條件類型。

Node.js

// before
const {onObjectDeleted} = require("firebase-functions/v2/storage");

exports.objectDeleted = onObjectDeleted((event) => {
    // ...
});

// after
const {onObjectArchived} = require("firebase-functions/v2/storage");

exports.objectArchived = onObjectArchived((event) => {
    // ...
});

Python

# before
from firebase_functions import storage_fn

@storage_fn.on_object_deleted()
def object_deleted(event):
  # ...

# after 
from firebase_functions import storage_fn

@storage_fn.on_object_archived()
def object_archived(event):
  # ...

接著執行下列指令,先建立新函式,然後再刪除舊函式:

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

# Wait until deployment is done; now both objectDeleted and objectArchived are running

# Delete objectDeleted
firebase functions:delete objectDeleted

設定執行階段選項

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 版本

Cloud Functions 專用的 Firebase SDK 可讓您選取 Node.js 執行階段。您可以選擇只在與下列任一受支援 Node.js 版本的執行階段環境中,執行專案中的所有函式:

  • Node.js 22 (預先發布版)
  • Node.js 20
  • Node.js 18

Node.js 14 和 16 版已淘汰,並將於 2025 年初停用。含有這些已淘汰版本的部署作業已停用。

如要設定 Node.js 版本:

您可以在初始化期間透過 functions/ 目錄建立的 package.json 檔案,在 engines 欄位中設定版本。舉例來說,如果只要使用 18 版,請在 package.json 中編輯下列程式碼:

  "engines": {"node": "20"}

如果您使用 Yarn 套件管理員,或對 engines 欄位有其他特定要求,可以改為在 firebase.json 中為 Cloud Functions 設定 Firebase SDK 的執行階段:

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs20
    }
  }

CLI 使用在 firebase.json 中設定的值,而不是您在 package.json 中另外設定的任何值或範圍。

升級 Node.js 執行階段

如要升級 Node.js 執行階段:

  1. 請確認您的專案採用 Blaze 定價方案
  2. 確認您使用的是 Firebase CLI v11.18.0 以上版本。
  3. 針對在初始化期間於 functions/ 目錄中建立的 package.json 檔案,變更 engines 值。舉例來說,如果您從 18 版升級至 20 版,項目應如下所示:"engines": {"node": "20"}
  4. 您也可以使用 Firebase 本機模擬器套件測試變更。
  5. 重新部署所有函式。

設定 Python 版本

Firebase SDK for Cloud Functions 12.0.0 以上版本允許選取 Python 執行階段。在 firebase.json 中設定執行階段版本,如下所示:

  {
    "functions": {
      "runtime": "python310" // or python311
    }
  }

控管資源調度行為

根據預設,Cloud Functions for Firebase 會根據傳入要求的數量調整運作中的執行個體數量,可能會在流量降低時縮減為零個執行個體。不過,如果您的應用程式需要縮短延遲時間,而您想要限製冷啟動的次數,則可變更這個預設行為。指定必須保持暖機狀態且準備好處理要求的最低容器執行個體數量。

同樣地,您可以設定上限數字,限制執行個體的資源調度,以回應傳入要求。使用這項設定來控制費用,或限制與服務 (例如資料庫) 的連線數量。

將這些設定與個別執行個體的並行設定 (第 2 代新功能) 搭配使用,您就能控制及調整函式的資源調度行為。應用程式和函式的性質會決定哪些設定最成本效益,並且能夠達到最佳效能。

對於某些流量偏低的應用程式,較低的 CPU 選項在沒有多並行的情況下是最佳選擇。而對於其他冷啟動是重大問題,設定高並行和執行個體數量下限可讓一組執行個體隨時保持暖機狀態,以處理大量的流量高峰。

對於流量極低的小型應用程式,若設定低並行且並行的低執行個體上限,應用程式可以處理爆發的流量,而不會產生過多費用。不過請注意,如果設定的執行個體數量上限太低,系統可能會在達到上限時捨棄要求。

允許並行要求

在 Cloud Functions for Firebase (第 1 代) 中,每個執行個體一次可以處理一個要求,因此資源調度行為僅設有執行個體下限和上限設定。除了控管執行個體數量以外,在 Cloud Functions for Firebase (第 2 代) 中,您還可以使用 concurrency 選項,控制每個執行個體可以同時處理的要求數量。並行的預設值為 80,但您可以將其設為介於 1 到 1000 之間的任何整數。

並行設定較高的函式可在不冷啟動的情況下吸收流量激增的情況,因為每個執行個體都有可能的空間。如果執行個體已設定為處理最多 50 個並行要求,但目前僅處理 25 個要求,則它可以處理 25 個尖峰的額外要求,無需新的執行個體啟動冷啟動。相反地,如果並行設定設為 1,則要求激增時,可能會導致 25 次冷啟動。

這個簡化的情境能證明並行的潛在效率提升。實際上,資源調度行為可最佳化效率,減少冷啟動,從並行作業開始變得較為複雜。Cloud Functions for Firebase 第 2 代的並行功能是由 Cloud Run 提供技術,並且會遵循 Cloud Run 的容器執行個體自動調度資源規則。

在 Cloud Functions for Firebase (第 2 代) 中實驗較高的並行設定時,請注意下列事項:

  • 較高的並行設定可能需要較高的 CPU 和 RAM 才能達到最佳效能,直到達到實際限制為止。舉例來說,如果函式需要進行大量圖片或影片處理作業,即使 CPU 和 RAM 設定已最大化,可能仍缺乏資源來處理 1,000 項並行要求。
  • 由於 Cloud Functions for Firebase (第 2 代) 採用 Cloud Run 技術,因此您也可以參閱 Google Cloud 的最佳化並行最佳化指南
  • 在實際工作環境中切換至多重並行之前,請務必先在測試環境中完整測試多並行。

將執行個體數量下限維持在暖機狀態

您可以在原始碼中,設定函式的執行個體數量下限。例如,這個函式會將至少 5 個執行個體設為暖機:

Node.js

const { onCall } = require("firebase-functions/v2/https");

exports.getAutocompleteResponse = onCall(
  {
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  },
  (event) => {
    // Autocomplete user’s search term
  }
);

Python

@https_fn.on_call(min_instances=5)
def get_autocomplete_response(event: https_fn.CallableRequest) -> https_fn.Response:

設定執行個體下限時,請注意下列事項:

  • 如果 Cloud Functions for Firebase 將應用程式的資源調度率高於設定值,則每個超過該門檻的執行個體都會遇到冷啟動。
  • 對於流量暴增的應用程式而言,冷啟動的效果最為嚴重。如果應用程式有激增的流量,而您設定的值夠高,能在每次流量增加時降低冷啟動,將大幅縮短延遲時間。如果應用程式的流量穩定,冷啟動不太可能會對效能造成嚴重影響。
  • 在實際工作環境中設定最低執行個體是合理的,但通常應避免在測試環境中使用。如要在測試專案中將資源調度降至零,同時減少實際工作環境專案中的冷啟動次數,您可以在參數化設定中將執行個體的最小值設定:

    Node.js

    const functions = require('firebase-functions');
    const { defineInt, defineString } = require('firebase-functions/params');
    
    // Define some parameters
    const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
    const welcomeMessage = defineString('WELCOME_MESSAGE');
    
    // To use configured parameters inside the config for a function, provide them 
    // directly. To use them at runtime, call .value() on them.
    export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
      (req, res) => {
        res.send(`${welcomeMessage.value()}! I am a function.`);
      }
    );
    

    Python

    MIN_INSTANCES = params.IntParam("HELLO_WORLD_MININSTANCES")
    WELCOME_MESSAGE = params.StringParam("WELCOME_MESSAGE")
    
    @https_fn.on_request(min_instances=MIN_INSTANCES.value())
    def get_autocomplete_response(event: https_fn.Request) -> https_fn.Response:
        return https_fn.Response(f"{WELCOME_MESSAGE.value()} I'm a function.")
    

限制函式的執行個體數量上限

您可以在函式原始碼中設定執行個體的數量上限值。 舉例來說,這個函式會將限制設為 100 個執行個體,以免破壞假想的舊版資料庫:

Node.js

const { onMessagePublished } = require("firebase-functions/v2/pubsub");

exports.mirrorevents = onMessagePublished(
  { topic: "topic-name", maxInstances: 100 },
  (event) => {
    // Connect to legacy database
  }
);

Python

@pubsub_fn.on_message_published(topic="topic-name", max_instances=100)
def mirrorevents(event: pubsub_fn.CloudEvent):
#  Connect to legacy database

如果 HTTP 函式擴充為執行個體數量上限,系統會將 30 秒的新要求排入佇列。如果屆時沒有可用執行個體,則會拒絕新的要求,並顯示回應代碼 429 Too Many Requests

如要進一步瞭解使用執行個體上限設定的最佳做法,請參閱設定執行個體上限的最佳做法

設定逾時和記憶體分配

在某些情況下,您的函式對於長時間的逾時值或大量記憶體配置可能有特殊需求。您可以在 Google Cloud 控制台或函式原始碼 (僅限 Firebase) 中設定這些值。

如要在函式原始碼中設定記憶體分配和逾時,請使用記憶體和逾時秒數的全域選項,自訂執行函式的虛擬機器。舉例來說,這個 Cloud Storage 函式會使用 1 GiB 的記憶體,並在 300 秒後逾時:

Node.js

exports.convertLargeFile = onObjectFinalized({
  timeoutSeconds: 300,
  memory: "1GiB",
}, (event) => {
  // Do some complicated things that take a lot of memory and time
});

Python

@storage_fn.on_object_finalized(timeout_sec=300, memory=options.MemoryOption.GB_1)
def convert_large_file(event: storage_fn.CloudEvent):
# Do some complicated things that take a lot of memory and time.

逾時秒數的最大值為 540 或 9 分鐘。

如何在 Google Cloud 控制台中設定記憶體分配和逾時:

  1. 在 Google Cloud 控制台中,從左選單選取「Cloud Functions for Firebase」
  2. 在函式清單中按一下函式名稱以選取函式。
  3. 按一下頂端選單中的「編輯」圖示。
  4. 從標示為「Memoryallocate」(記憶體分配) 的下拉式選單中選取記憶體分配。
  5. 按一下「More」即可顯示進階選項,然後在「Timeout」(逾時) 文字方塊中輸入秒數。
  6. 按一下「Save」(儲存) 以更新函式。

覆寫 CPU 預設值

分配最多 2 GB 的記憶體。Cloud Functions for Firebase (第 2 代) 中的每個函式預設為一個 CPU,然後增加到 2 個 CPU (4 和 8 GB)。請注意,這與第 1 代的預設行為有很大的差異,這可能導致低記憶體函式產生的成本略高,如下表所示:

分配的 RAM 版本 1 預設 CPU (小數) 版本 2 預設 CPU 每毫秒價格調漲
128MB 1/12 1 種 10.5 倍
256MB 1/6 1 種 5.3 倍
512MB 1/3 1 種 2.7 倍
1GB 7 月 12 日 1 種 1.6 倍
2GB 1 種 1 種 1 倍
4GB 2 2 1 倍
8GB 2 2 1 倍
16 GB 不適用 4 不適用

如果想讓第 2 代函式使用第 1 代行為,請將第 1 代預設值設為全域選項:

Node.js

// Turn off Firebase defaults
setGlobalOptions({ cpu: 'gcf_gen1' });

Python

# Use 1st gen behavior
set_global_options(cpu="gcf_gen1")

針對會耗用大量 CPU 的函式,第 2 代可彈性設定額外的 CPU。您可以針對每個函式強化 CPU,如下所示:

Node.js

// Boost CPU in a function:
export const analyzeImage = onObjectFinalized({ cpu: 2 }, (event) => {
  // computer vision goes here
});

Python

# Boost CPU in a function:
@storage_fn.on_object_finalized(cpu=2)
def analyze_image(event: storage_fn.CloudEvent):
# computer vision goes here