您通常需要為函式進行額外設定,例如第三方 API 金鑰或可調整的設定。Firebase SDK for Cloud Functions 提供內建的環境設定,方便您儲存及擷取專案的這類資料。
你可以選擇下列任一選項:
- 參數化設定 (建議用於大多數情境)。這會提供強型別環境設定,以及在部署時驗證的參數,可避免錯誤並簡化偵錯程序。
- 以檔案為基礎設定環境變數。使用這種方法時,您需要手動建立 dotenv 檔案,載入環境變數。
在多數情況下,建議使用參數化設定。這種做法可讓設定值在執行階段和部署階段都可用,且除非所有參數都有有效值,否則部署作業會遭到封鎖。反之,部署時無法使用環境變數設定。
參數化設定
Cloud Functions for Firebase 提供介面,可在程式碼集內以宣告方式定義設定參數。在函式部署期間、設定部署和執行階段選項時,以及執行期間,都可以使用這些參數的值。也就是說,除非所有參數都有有效值,否則 CLI 會封鎖部署作業。
Node.js
const { onRequest } = require('firebase-functions/v2/https');
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 = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
# To use configured parameters inside the config for a function, provide them
# directly. To use them at runtime, call .value() on them.
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
部署含有參數化設定變數的函式時,Firebase CLI 會先嘗試從本機 .env 檔案載入這些變數的值。如果這些檔案中沒有這些值,且未設定 default
,CLI 會在部署期間提示輸入值,然後自動將這些值儲存至 functions/
目錄中名為 .env.<project_ID>
的 .env
檔案:
$ firebase deploy
i functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i functions: Loaded environment variables from .env.projectId
視開發工作流程而定,將產生的 .env.<project_ID>
檔案加入版本控管可能很有用。
在全域範圍中使用參數
部署期間,系統會先載入並檢查函式程式碼,然後才會為參數提供實際值。也就是說,如果在全域範圍內擷取參數值,就會導致部署失敗。如要使用參數初始化全域值,請使用初始化回呼 onInit()
。這個回呼會在任何函式於正式環境中執行前執行,但不會在部署期間呼叫,因此是存取參數值的安全位置。
Node.js
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { defineSecret } = require('firebase-functions/params');
const { onInit } = require('firebase-functions/v2/core');
const apiKey = defineSecret('GOOGLE_API_KEY');
let genAI;
onInit(() => {
genAI = new GoogleGenerativeAI(apiKey.value());
})
Python
from firebase_functions.core import init
from firebase_functions.params import StringParam, PROJECT_ID
import firebase_admin
import vertexai
location = StringParam("LOCATION")
x = "hello"
@init
def initialize():
# Note: to write back to a global, you'll need to use the "global" keyword
# to avoid creating a new local with the same name.
global x
x = "world"
firebase_admin.initialize_app()
vertexai.init(PROJECT_ID.value, location.value)
如果您使用 Secret
類型的參數,請注意,這些參數僅適用於已繫結密鑰的函式程序。如果密鑰只繫結在部分函式中,請先檢查 secret.value()
是否為假值,再使用密鑰。
設定 CLI 行為
您可以透過 Options
物件設定參數,控管 CLI 提示輸入值的方式。下列範例會設定選項,驗證電話號碼格式、提供簡單的選取選項,以及從 Firebase 專案自動填入選取選項:
Node.js
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});
const onlyPhoneNumbers = defineString('PHONE_NUMBER', {
input: {
text: {
validationRegex: /\d{3}-\d{3}-\d{4}/,
validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"
},
},
});
const selectedOption = defineString('PARITY', {input: params.select(["odd", "even"])});
const memory = defineInt("MEMORY", {
description: "How much memory do you need?",
input: params.select({ "micro": 256, "chonky": 2048 }),
});
const extensions = defineList("EXTENSIONS", {
description: "Which file types should be processed?",
input: params.multiSelect(["jpg", "tiff", "png", "webp"]),
});
const storageBucket = defineString('BUCKET', {
description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets",
input: params.PICK_STORAGE_BUCKET,
});
Python
from firebase_functions.params import (
StringParam,
ListParam,
TextInput,
SelectInput,
SelectOptions,
ResourceInput,
ResourceType,
)
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
WELCOME_MESSAGE = StringParam(
"WELCOME_MESSAGE",
default="Hello World",
description="The greeting that is returned to the caller of this function",
)
ONLY_PHONE_NUMBERS = StringParam(
"PHONE_NUMBER",
input=TextInput(
validation_regex="\d{3}-\d{3}-\d{4}",
validation_error_message="Please enter a phone number in the format XXX-YYY-XXX",
),
)
SELECT_OPTION = StringParam(
"PARITY",
input=SelectInput([SelectOptions(value="odd"), SelectOptions(value="even")]),
)
STORAGE_BUCKET = StringParam(
"BUCKET",
input=ResourceInput(type=ResourceType.STORAGE_BUCKET),
description="This will automatically populate the selector field with the deploying Cloud Project's storage buckets",
)
參數類型
參數化設定可為參數值提供嚴格型別,並支援 Cloud Secret Manager 中的密鑰。支援的類型如下:
- 密鑰
- 字串
- 布林值
- 整數
- 浮點值
- 清單 (Node.js)
參數值和運算式
Firebase 會在部署時和函式執行期間評估參數。由於有這兩個環境,比較參數值時必須格外小心,使用參數值為函式設定執行階段選項時也是如此。
如要以執行階段選項的形式將參數傳遞至函式,請直接傳遞:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam
MIN_INSTANCES = IntParam("HELLO_WORLD_MIN_INSTANCES")
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
此外,如要與參數比較,瞭解該選擇哪個選項,您必須使用內建比較子,而不是檢查值:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const environment = params.defineString(‘ENVIRONMENT’, {default: 'dev'});
// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = onRequest(
{ minInstances: minInstancesConfig },
(req, res) => {
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import IntParam, StringParam
ENVIRONMENT = StringParam("ENVIRONMENT", default="dev")
MIN_INSTANCES = ENVIRONMENT.equals("PRODUCTION").then(10, 0)
@https_fn.on_request(min_instances=MIN_INSTANCES)
def hello_world(req):
...
如要存取僅在執行階段使用的參數和參數運算式,可以使用 value
函式:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');
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 = onRequest(
(req, res) => {
res.send(`${welcomeMessage.value()}! I am a function.`);
}
);
Python
from firebase_functions import https_fn
from firebase_functions.params import StringParam
WELCOME_MESSAGE = StringParam("WELCOME_MESSAGE")
@https_fn.on_request()
def hello_world(req):
return https_fn.Response(f'{WELCOME_MESSAGE.value()}! I am a function!')
內建參數
Cloud Functions SDK 提供三個預先定義的參數,可從 firebase-functions/params
子套件取得:
Node.js
projectID
:函式執行的 Cloud 專案。databaseURL
:與函式相關聯的即時資料庫執行個體網址 (如果已在 Firebase 專案中啟用)。storageBucket
:與函式相關聯的 Cloud Storage 值區 (如果已在 Firebase 專案中啟用)。
Python
PROJECT_ID
:函式執行的 Cloud 專案。DATABASE_URL
:與函式相關聯的即時資料庫執行個體網址 (如果已在 Firebase 專案中啟用)。STORAGE_BUCKET
:與函式相關聯的 Cloud Storage 值區 (如果已在 Firebase 專案中啟用)。
這些函式在各方面都與使用者定義的字串參數類似,但由於 Firebase CLI 一律會知道這些函式的值,因此在部署時不會提示輸入值,也不會儲存至 .env
檔案。
密鑰參數
使用 defineSecret()
定義的 Secret
類型參數代表字串參數,這些參數的值儲存在 Cloud Secret Manager 中。密鑰參數會檢查 Cloud Secret Manager 中是否存在密鑰,並在部署期間互動式提示輸入新密鑰的值,而不是檢查本機 .env
檔案,並在缺少密鑰時將新值寫入檔案。
以這種方式定義的密鑰參數必須繫結至應有權存取這些參數的個別函式:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');
export const postToDiscord = onRequest(
{ secrets: [discordApiKey] },
(req, res) => {
const apiKey = discordApiKey.value();
//…
Python
from firebase_functions import https_fn
from firebase_functions.params import SecretParam
DISCORD_API_KEY = SecretParam('DISCORD_API_KEY')
@https_fn.on_request(secrets=[DISCORD_API_KEY])
def post_to_discord(req):
api_key = DISCORD_API_KEY.value
由於密鑰值會在函式執行前隱藏,因此您無法在設定函式時使用這些值。
環境變數
Cloud Functions for Firebase 支援 dotenv 檔案格式,可將 .env
檔案中指定的環境變數載入應用程式執行階段。部署完成後,即可透過 process.env
介面 (適用於以 Node.js 為基礎的專案) 或 os.environ
(適用於以 Python 為基礎的專案) 讀取環境變數。
如要透過這種方式設定環境,請在專案中建立 .env
檔案、新增所需變數,然後部署:
在
functions/
目錄中建立.env
檔案:# Directory layout: # my-project/ # firebase.json # functions/ # .env # package.json # index.js
開啟
.env
檔案進行編輯,然後新增所需金鑰。例如:PLANET=Earth AUDIENCE=Humans
部署函式並確認環境變數已載入:
firebase deploy --only functions # ... # i functions: Loaded environment variables from .env. # ...
自訂環境變數部署完成後,函式程式碼即可存取這些變數:
Node.js
// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
Python
import os
@https_fn.on_request()
def hello(req):
return https_fn.Response(
f"Hello {os.environ.get('PLANET')} and {os.environ.get('AUDIENCE')}"
)
部署多組環境變數
如果 Firebase 專案需要另一組環境變數 (例如測試環境與正式環境),請建立 .env.<project or
alias>
檔案,並在其中寫入專案專屬的環境變數。.env
和專案專屬 .env
檔案 (如有) 中的環境變數會納入所有已部署的函式。
舉例來說,專案可能包含下列三個檔案,其中包含開發和正式環境略有不同的值:
.env
|
.env.dev
|
.env.prod
|
PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Prod Humans |
根據這些個別檔案中的值,與函式一併部署的環境變數集會因目標專案而異:
$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Dev Humans
$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
# PLANET=Earth
# AUDIENCE=Prod Humans
保留的環境變數
部分環境變數鍵保留供內部使用。請勿在 .env
檔案中使用下列任何金鑰:
- 所有以 X_GOOGLE_ 開頭的金鑰
- 所有以 EXT_ 開頭的鍵
- 所有以 FIREBASE_ 開頭的鍵
- 下列清單中的任何鍵:
- CLOUD_RUNTIME_CONFIG
- ENTRY_POINT
- GCP_PROJECT
- GCLOUD_PROJECT
- GOOGLE_CLOUD_PROJECT
- FUNCTION_TRIGGER_TYPE
- FUNCTION_NAME
- FUNCTION_MEMORY_MB
- FUNCTION_TIMEOUT_SEC
- FUNCTION_IDENTITY
- FUNCTION_REGION
- FUNCTION_TARGET
- FUNCTION_SIGNATURE_TYPE
- K_SERVICE
- K_REVISION
- PORT
- K_CONFIGURATION
儲存及存取機密設定資訊
儲存在 .env
檔案中的環境變數可用於函式設定,但不建議您將這類變數視為安全儲存方式,用來儲存資料庫憑證或 API 金鑰等機密資訊。如果您將 .env
檔案存入原始碼控管,這一點就格外重要。
為協助您儲存機密設定資訊,Cloud Functions for Firebase與 Google Cloud Secret Manager 整合。這項加密服務會安全地儲存設定值,同時允許函式在需要時輕鬆存取。
建立及使用密鑰
如要建立密鑰,請使用 Firebase CLI。
如何建立及使用密鑰:
在本地專案目錄的根目錄中執行下列指令:
firebase functions:secrets:set SECRET_NAME
輸入 SECRET_NAME 的值。
CLI 會回覆成功訊息,並警告您必須部署函式,變更才會生效。
部署前,請確認函式程式碼允許函式使用
runWith
參數存取密鑰:Node.js
const { onRequest } = require('firebase-functions/v2/https'); exports.processPayment = onRequest( { secrets: ["SECRET_NAME"] }, (req, res) => { const myBillingService = initializeBillingService( // reference the secret value process.env.SECRET_NAME ); // Process the payment } );
Python
import os from firebase_functions import https_fn @https_fn.on_request(secrets=["SECRET_NAME"]) def process_payment(req): myBillingService = initialize_billing(key=os.environ.get('SECRET_NAME')) # Process the payment ...
部署 Cloud Functions:
firebase deploy --only functions
現在,您就能像存取其他環境變數一樣存取這個變數。 反之,如果另一個未在
runWith
中指定密鑰的函式嘗試存取密鑰,則會收到未定義的值:Node.js
exports.anotherEndpoint = onRequest((request, response) => { response.send(`The secret API key is ${process.env.SECRET_NAME}`); // responds with "The secret API key is undefined" because the `runWith` parameter is missing });
Python
@https_fn.on_request() def another_endpoint(req): return https_fn.Response(f"The secret API key is {os.environ.get("SECRET_NAME")}") # Responds with "The secret API key is None" because the `secrets` parameter is missing.
函式部署完畢後,即可存取密鑰值。只有在 runWith
參數中明確包含密鑰的函式,才能以環境變數的形式存取該密鑰。這有助於確保只有在需要時才能存取密鑰值,降低密鑰意外外洩的風險。
管理密鑰
使用 Firebase CLI 管理密鑰。以這種方式管理密鑰時,請注意,部分 CLI 變更需要您修改及/或重新部署相關聯的函式。具體步驟包括:
- 每當您為密鑰設定新值時,都必須重新部署參照該密鑰的所有函式,才能讓這些函式採用最新值。
- 刪除密鑰時,請確認已部署的函式未參照該密鑰。如果函式使用的密鑰值已刪除,系統不會發出任何通知。
以下是密鑰管理適用的 Firebase CLI 指令摘要:
# Change the value of an existing secret firebase functions:secrets:set SECRET_NAME # View the value of a secret functions:secrets:access SECRET_NAME # Destroy a secret functions:secrets:destroy SECRET_NAME # View all secret versions and their state functions:secrets:get SECRET_NAME # Automatically clean up all secrets that aren't referenced by any of your functions functions:secrets:prune
如為 access
和 destroy
指令,您可以提供選用的版本參數來管理特定版本。例如:
functions:secrets:access SECRET_NAME[@VERSION]
如要進一步瞭解這些作業,請在指令中傳遞 -h
,查看 CLI 說明。
Secret 的計費方式
Secret Manager 可免費提供 6 個有效密鑰版本。也就是說,每個 Firebase 專案每月可免費使用 6 個密鑰。
根據預設,Firebase CLI 會在適當情況下自動銷毀未使用的密鑰版本,例如部署含有新版密鑰的函式時。此外,您可以使用 functions:secrets:destroy
和 functions:secrets:prune
主動清除未使用的密鑰。
Secret Manager 可對密鑰執行 10,000 次免付費的每月存取作業。函式執行個體每次冷啟動時,只會讀取 runWith
參數中指定的密鑰。如果有很多函式例項讀取大量密鑰,專案可能會超過這項配額,屆時系統會針對每 10,000 次存取作業收取 $0.03 美元。
詳情請參閱「Secret Manager 定價」。
模擬器支援
使用 dotenv 進行環境設定時,會與本機 Cloud Functions 模擬器互通。
使用本機 Cloud Functions 模擬器時,您可以設定 .env.local
檔案,覆寫專案的環境變數。.env.local
的內容優先於 .env
和專案專屬的 .env
檔案。
舉例來說,專案可能包含下列三個檔案,其中包含開發和本機測試的略有不同值:
.env
|
.env.dev
|
.env.local
|
PLANET=Earth
AUDIENCE=Humans |
AUDIENCE=Dev Humans | AUDIENCE=Local Humans |
在本地環境啟動時,模擬器會載入環境變數,如下所示:
$ firebase emulators:start
i emulators: Starting emulators: functions
# Starts emulator with following environment variables:
# PLANET=Earth
# AUDIENCE=Local Humans
Cloud Functions 模擬器中的密鑰和憑證
Cloud Functions 模擬器支援使用密鑰儲存及存取機密設定資訊。根據預設,模擬器會嘗試使用應用程式預設憑證存取正式版密鑰。在 CI 環境等特定情況下,模擬器可能會因權限限制而無法存取密鑰值。
與 Cloud Functions 模擬器支援環境變數類似,您可以設定 .secret.local
檔案,覆寫密鑰值。這樣您就能輕鬆在本機測試函式,特別是當您無法存取密鑰值時。
從環境設定遷移
如果您一直使用 functions.config
進行環境設定,請務必在 2025 年底前,將現有設定遷移為環境變數 (dotenv 格式),因為 functions.config
將於 2025 年底停用。2025 年 12 月後,使用 functions.config
的新部署作業將會失敗。
Firebase CLI 提供匯出指令,可將目錄 .firebaserc
檔案中列出的每個別名或專案 (在下列範例中為 local
、dev
和 prod
) 的設定輸出為 .env
檔案。
如要遷移,請使用 firebase functions:config:export
指令匯出現有環境設定:
firebase functions:config:export i Importing configs from projects: [project-0, project-1] ⚠ The following configs keys could not be exported as environment variables: ⚠ project-0 (dev): 1foo.a => 1FOO\_A (Key 1FOO\_A must start with an uppercase ASCII letter or underscore, and then consist of uppercase ASCII letters, digits, and underscores.) Enter a PREFIX to rename invalid environment variable keys: CONFIG\_ ✔ Wrote functions/.env.prod ✔ Wrote functions/.env.dev ✔ Wrote functions/.env.local ✔ Wrote functions/.env
請注意,在某些情況下,系統會提示您輸入前置字元,重新命名匯出的環境變數金鑰。這是因為部分設定可能無效或屬於保留的環境變數金鑰,因此無法自動轉換。
建議您在部署函式或將 .env
檔案簽入來源控管之前,仔細檢查產生的 .env
檔案內容。如有任何值屬於機密資訊,不應外洩,請從 .env
檔案中移除這些值,並改為安全地儲存在 Secret Manager 中。
您也需要更新函式程式碼。使用 functions.config
的函式現在必須改用 process.env
,如「環境變數」一節所示。