您可以使用 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測試您的更改。
- 重新部署所有功能。
設置Python版本
Firebase SDK for Cloud Functions 版本 12.0.0 及更高版本允許選擇 Python 運行時(用於公共預覽功能)。在firebase.json
中設置運行時版本,如下所示:
{
"functions": {
"runtime": "python310" // or python311
}
}
控制縮放行為
默認情況下,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 。
- 通過在函數列表中單擊函數名稱來選擇函數。
- 單擊頂部菜單中的編輯圖標。
- 從標有“已分配內存”的下拉菜單中選擇內存分配。
- 單擊“更多”以顯示高級選項,然後在“超時”文本框中輸入秒數。
- 單擊“保存”以更新函數。