您可以使用 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 Console 。
- 透過在部署之前從來源中刪除該函數來隱式實現。
所有刪除操作都會在從生產中刪除該功能之前提示您確認。
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
更改函數的一個或多個區域
如果您要變更處理生產流量的函數的指定區域,則可以透過依序執行下列步驟來防止事件遺失:
- 重新命名函數,並根據需要更改其一個或多個區域。
- 部署重命名的函數,這會導致在兩組區域中暫時執行相同的程式碼。
- 刪除之前的功能。
例如,如果您有一個名為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
現在有兩個相同的函數正在運行: webhook
在us-central1
中運行,而webhookAsia
在asia-northeast1
中運行。
然後,刪除webhook
:
firebase functions:delete webhook
現在只有一個函數 - webhookAsia
,它在asia-northeast1
中運行。
更改函數的觸發類型
隨著時間的推移,當您開發 Cloud Functions for Firebase 部署時,您可能會因各種原因需要變更函數的觸發器類型。例如,您可能想要從一種類型的 Firebase 即時資料庫或 Cloud Firestore 事件變更為另一種類型。
僅透過更改原始程式碼並運行firebase deploy
來更改函數的事件類型是不可能的。為了避免錯誤,請透過下列程序變更函數的觸發器類型:
- 修改原始程式碼以包含具有所需觸發類型的新函數。
- 部署該函數,這會導致臨時運行舊函數和新函數。
- 使用 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 會將程式碼中設定的執行時間選項與目前部署的函數版本的設定合併,優先順序如下:
- 選項在功能代碼中設定:覆蓋外部變更。
- 選項在功能代碼中設定為
RESET_VALUE
:使用預設值覆寫外部變更。 - 選項不在函數程式碼中設置,但在目前部署的函數中設定:使用已部署函數中指定的選項。
在大多數情況下,不建議使用preserveExternalChanges: true
選項,因為您的程式碼將不再是函數執行時間選項的完整來源。如果您確實使用它,請檢查 Google Cloud 控制台或使用 gcloud CLI 查看函數的完整配置。
設定 Node.js 版本
適用於 Cloud Functions 的 Firebase SDK 允許選擇 Node.js 執行時期。您可以選擇在與下列受支援的 Node.js 版本之一對應的執行階段環境上專門執行專案中的所有函數:
- Node.js 20 (預覽版)
- Node.js 18
- Node.js 16
- Node.js 14
設定 Node.js 版本:
您可以在初始化期間在functions/
目錄中建立的package.json
檔案的engines
欄位中設定版本。例如,若要僅使用版本 18,請在package.json
中編輯以下行:
"engines": {"node": "18"}
如果您使用 Yarn 套件管理器或對engines
欄位有其他特定要求,則可以在firebase.json
中設定 Firebase SDK for Cloud Functions 的執行時間:
{
"functions": {
"runtime": "nodejs18" // or nodejs14, nodejs16 or nodejs20
}
}
CLI 優先使用firebase.json
中設定的值,而不是您在package.json
中單獨設定的任何值或範圍。
升級您的 Node.js 運行時
升級 Node.js 執行時期:
- 確保您的項目在Blaze 定價計劃中。
- 確保您使用的是 Firebase CLI v11.18.0 或更高版本。
- 變更初始化期間在
functions/
目錄中建立的package.json
檔案中的engines
值。例如,如果您要從版本 16 升級到版本 18,則條目應如下所示:"engines": {"node": "18"}
- (可選)使用Firebase Local Emulator Suite測試您的變更。
- 重新部署所有功能。
控制縮放行為
預設情況下,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 對象,該介面定義timeoutSeconds
和memory
的值。例如,這個儲存函數使用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.4GHz -
2GB
— 2.4GHz -
4GB
— 4.8GHz -
8GB
— 4.8GHz
要在 Google Cloud Console 中設定記憶體分配和逾時:
- 在 Google Google Cloud Console 中,從左側選單中選擇Cloud Functions 。
- 透過在函數清單中點選函數名稱來選擇函數。
- 點擊頂部選單中的編輯圖示。
- 從標示「已分配記憶體」的下拉式選單中選擇記憶體分配。
- 按一下「更多」以顯示進階選項,然後在「逾時」文字方塊中輸入秒數。
- 點擊“儲存”以更新函數。