如果應用程式目前使用第 1 代函式,則應考慮遷移至第 2 代 請務必提供本指南說明第 2 代函式會使用 Cloud Run 包括改善效能、改善設定、監控效能,以及執行其他操作。
本頁中的範例假設您使用 JavaScript 執行 CommonJS 模組
(匯入 require
樣式),但使用 ESM 的 JavaScript 也適用相同的原則
(import … from
樣式匯入) 和 TypeScript。
遷移程序
第 1 代和第 2 代函式可以在同一個檔案中並列顯示。這個 可讓您輕鬆地進行個別遷移。建議做法 一次遷移一個函式,並在之前執行測試與驗證 繼續。
驗證 Firebase CLI 和 firebase-function
s 版本
確認您使用的是至少 Firebase CLI 版本 12.00
,並且
firebase-functions
版 4.3.0
。任何較新版本都支援第 2 代
和第 1 代
更新匯入作業
從 firebase-functions
SDK 中的 v2
子套件匯入的第 2 代函式。
這個不同的匯入路徑,是 Firebase CLI 判斷是否要
將函式程式碼部署為第 1 代或第 2 代函式。
v2
子套件是模組化的,建議您僅匯入
所需的模組
變更前:第 1 代
const functions = require("firebase-functions/v1");
變更後:第 2 代
// explicitly import each trigger
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
更新觸發條件定義
由於第 2 代 SDK 偏好模組匯入,請將觸發條件定義更新為 反映上一個步驟中已變更的匯入內容。
在某些觸發條件中傳遞到回呼的引數已變更。在本
例如,請注意,onDocumentCreated
回呼的引數已加上
整合成單一 event
物件此外,部分觸發條件
方便的新設定功能,例如 onRequest
觸發條件的 cors
如果有需要 SQL 指令的分析工作負載
則 BigQuery 可能是最佳選擇
變更前:第 1 代
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions.firestore
.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
變更後:第 2 代
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
exports.date = onRequest({cors: true}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
使用參數化設定
第 2 代函式支援 functions.config
,改用更安全的介面,在程式碼集中以宣告方式定義設定參數。使用新的 params
模組時,除非所有參數具有有效值,否則 CLI 會封鎖部署作業,確保部署函式時並未缺少設定。
遷移至 params
子套件
如果您已透過 functions.config
使用環境設定,
您就能將現有設定
「參數化設定」一節。
變更前:第 1 代
const functions = require("firebase-functions/v1");
exports.date = functions.https.onRequest((req, res) => {
const date = new Date();
const formattedDate =
date.toLocaleDateString(functions.config().dateformat);
// ...
});
變更後:第 2 代
const {onRequest} = require("firebase-functions/v2/https");
const {defineString} = require("firebase-functions/params");
const dateFormat = defineString("DATE_FORMAT");
exports.date = onRequest((req, res) => {
const date = new Date();
const formattedDate = date.toLocaleDateString(dateFormat.value());
// ...
});
設定參數值
第一次部署時,Firebase CLI 會提示輸入
參數,並將值儲存在 dotenv 檔案中。如要匯出
functions.config 值,執行 firebase functions:config:export
。
特殊情況:API 金鑰
params
模組與 Cloud Secret Manager 整合,
精細的存取權控管機制,集中管理 API 金鑰等機密值。詳情請見
秘密參數
瞭解詳情
變更前:第 1 代
const functions = require("firebase-functions/v1");
exports.getQuote = functions.https.onRequest(async (req, res) => {
const quote = await fetchMotivationalQuote(functions.config().apiKey);
// ...
});
變更後:第 2 代
const {onRequest} = require("firebase-functions/v2/https");
const {defineSecret} = require("firebase-functions/params");
// Define the secret parameter
const apiKey = defineSecret("API_KEY");
exports.getQuote = onRequest(
// make the secret available to this function
{ secrets: [apiKey] },
async (req, res) => {
// retrieve the value of the secret
const quote = await fetchMotivationalQuote(apiKey.value());
// ...
}
);
設定執行階段選項
執行階段選項設定 在第 1 代和第 2 代之間已有所變化第 2 代還增添了一項新功能 設定所有函式的選項。
變更前:第 1 代
const functions = require("firebase-functions/v1");
exports.date = functions
.runWith({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
})
// locate function closest to users
.region("asia-northeast1")
.https.onRequest((req, res) => {
// ...
});
exports.uppercase = functions
// locate function closest to users and database
.region("asia-northeast1")
.firestore.document("my-collection/{docId}")
.onCreate((change, context) => {
// ...
});
變更後:第 2 代
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");
const {setGlobalOptions} = require("firebase-functions/v2");
// locate all functions closest to users
setGlobalOptions({ region: "asia-northeast1" });
exports.date = onRequest({
// Keep 5 instances warm for this latency-critical function
minInstances: 5,
}, (req, res) => {
// ...
});
exports.uppercase = onDocumentCreated("my-collection/{docId}", (event) => {
/* ... */
});
使用並行
第 2 代函式的一大優點是 可同時處理多項要求這種做法可大幅減少 使用者遇到的冷啟動次數。根據預設,並行作業為 設為 80,但您可以將其設為 1 到 1000 之間的任何值:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// set concurrency value
concurrency: 500
},
(req, res) => {
// ...
});
調整並行可以提高效能並降低函式成本。 如要進一步瞭解並行,請參閱允許並行要求。
稽核全域變數使用情形
第 1 代在不考量並行的情況下編寫的函式可能會使用全域變數 根據每項要求設定及讀取的 Pod 數量當並行啟用時 執行個體會一次開始處理多個要求, 作為並行要求,開始設定及讀取全域變數 。
升級時,您可以將函式的 CPU 設為 gcf_gen1
及 concurrency
即可還原第 1 代行為:
const {onRequest} = require("firebase-functions/v2/https");
exports.date = onRequest({
// TEMPORARY FIX: remove concurrency
cpu: "gcf_gen1",
concurrency: 1
},
(req, res) => {
// ...
});
但我們不建議長期採用,因為這個做法會使 第 2 代函式的效能優勢改為稽核全球用量 變數,並且在您 準備好
將流量遷移至新的第 2 代函式
就像變更函式的區域或觸發條件類型一樣,您必須為第 2 代函式指定新名稱,並慢慢將流量遷移至該函式。
您無法使用相同名稱將函式從第 1 代升級至第 2 代,並執行 firebase deploy
。這麼做會導致錯誤:
Upgrading from GCFv1 to GCFv2 is not yet supported. Please delete your old function or wait for this feature to be ready.
在執行下列步驟前,請先確認您的函式為冪等,因為新版和舊版函式會在變更同時同時執行。舉例來說,如果您的第 1 代函式會回應 Firestore 中的寫入事件,請務必針對第 1 代函式和第 2 代函式分別回應寫入兩次,以便回應這些事件,讓應用程式呈現一致的狀態。
- 重新命名函式程式碼中的函式。例如將
resizeImage
重新命名為resizeImageSecondGen
。 - 部署函式,讓原本的第 1 代和第 2 代函式同時運作。
- 如果是可呼叫、工作佇列和 HTTP 觸發條件,請將用戶端程式碼更新為第 2 代函式的名稱或網址,開始將所有用戶端指向第 2 代函式。
- 透過背景觸發條件,第 1 代和第 2 代函式會在部署後立即回應每個事件。
- 關閉所有流量後,請使用 Firebase CLI 的
firebase functions:delete
指令刪除第 1 代函式。- 您可以選擇重新命名第 2 代函式,以符合第 1 代函式的名稱。