Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

配置您的環境

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

通常您需要為您的功能進行額外的配置,例如第三方 API 密鑰或可調整的設置。適用於 Cloud Functions 的 Firebase SDK 提供內置環境配置,可以輕鬆為您的項目存儲和檢索此類數據。

您可以在三個選項中進行選擇:

  • 參數化配置(推薦用於大多數場景)。這提供了帶有在部署時驗證的參數的強類型環境配置,從而防止錯誤並簡化調試。
  • 基於文件的環境變量配置。使用這種方法,您可以手動創建一個dotenv文件來加載環境變量。
  • 使用 Firebase CLI 和functions.config進行運行時環境配置

對於大多數用例,建議使用參數化配置。這種方法使配置值在運行時和部署時都可用,除非所有參數都具有有效值,否則部署將被阻止。相反,帶有環境變量的配置在部署時不可用。

參數化配置

Cloud Functions for Firebase 提供了一個接口,用於在您的代碼庫中以聲明方式定義配置參數。這些參數的值在函數部署期間、設置部署和運行時選項時以及執行期間均可用。這意味著 CLI 將阻止部署,除非所有參數都具有有效值。

要在代碼中定義參數,請遵循以下模型:

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.`);
  }
);

使用參數化配置變量部署函數時,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>文件添加到版本控制中可能會有用。

配置 CLI 行為

可以使用Options對象配置參數,該對象控制 CLI 如何提示輸入值。以下示例設置選項以驗證電話號碼的格式,提供簡單的選擇選項,並從 Firebase 項目自動填充選擇選項:

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: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

參數類型

參數化配置為參數值提供強類型,還支持來自 Cloud Secret Manager 的秘密。支持的類型有:

  • 秘密
  • 細繩
  • 布爾值
  • 整數
  • 漂浮

參數值和表達式

Firebase 會在部署時和函數執行時評估您的參數。由於這些雙重環境,在比較參數值以及使用它們為函數設置運行時選項時必須格外小心。

要將參數作為運行時選項傳遞給您的函數,請直接傳遞它:

const functions = require('firebase-functions');
const { defineInt} = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

此外,如果您需要與參數進行比較以了解選擇哪個選項,則需要使用內置比較器而不是檢查值:

const functions = require('firebase-functions');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(‘ENVIRONMENT’, {default: ‘dev’});

// use built-in comparators
const minInstancesConfig =environment.equals('PRODUCTION').thenElse(10, 1);
export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
  (req, res) => {
    //…

僅在運行時使用的參數和參數表達式可以通過它們的value函數訪問:

const functions = require('firebase-functions');
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 = functions.https.onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

內置參數

Cloud Functions SDK 提供三個預定義參數,可從firebase-functions/params子包中獲取:

  • projectId — 運行函數的 Cloud 項目。
  • databaseUrl — 與函數關聯的實時數據庫實例的 URL(如果在 Firebase 項目上啟用)。
  • storageBucket — 與函數關聯的 Cloud Storage 存儲桶(如果在 Firebase 項目上啟用)。

這些功能在所有方面都類似於用戶定義的字符串參數,除了因為它們的值始終為 Firebase CLI 所知,它們的值永遠不會在部署時被提示,也不會保存到.env文件中。

秘密參數

使用defineSecret()定義的Secret類型的參數表示具有存儲在 Cloud Secret Manager 中的值的字符串參數。與檢查本地.env文件並在丟失時向文件寫入新值不同,秘密參數檢查 Cloud Secret Manager 中是否存在,並在部署期間以交互方式提示輸入新秘密的值。

以這種方式定義的秘密參數必須綁定到應該訪問它們的各個函數:

const functions = require('firebase-functions');
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const postToDiscord = functions.runWith({ secrets: [discordApiKey] }).https.onRequest(
  (req, res) => {
    const apiKey = discordApiKey.value();
    //…

因為秘密的值在函數執行之前是隱藏的,所以您不能在配置函數時使用它們。

環境變量

Cloud Functions for Firebase 支持dotenv文件格式,用於將.env文件中指定的環境變量加載到您的應用程序運行時。部署後,可以通過process.env接口讀取環境變量。

要以這種方式配置您的環境,請在您的項目中創建一個.env文件,添加所需的變量,然後部署:

  1. 在您的functions/目錄中創建一個.env文件:

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. 打開.env文件進行編輯,並添加所需的密鑰。例如:

    PLANET=Earth
    AUDIENCE=Humans
    
  3. 部署函數並驗證是否加載了環境變量:

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

部署自定義環境變量後,您的函數代碼可以使用process.env語法訪問它們:

// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

部署多組環境變量

如果您的 Firebase 項目需要一組替代環境變量(例如暫存與生產),請創建一個.env. <project or alias >文件並在其中寫入項目特定的環境變量。來自.env和項目特定.env文件(如果存在)的環境變量將包含在所有已部署的函數中。

例如,一個項目可能包括這三個文件,其中包含用於開發和生產的略有不同的值:

.env .env.dev .env.prod
行星=地球

觀眾=人類

觀眾=開發人員觀眾=生產人類

鑑於這些單獨文件中的值,與您的函數一起部署的環境變量集將根據您的目標項目而有所不同:

$ 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
  • 入口點
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • 功能區域
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_服務
  • K_修訂版
  • 港口
  • K_配置

存儲和訪問敏感的配置信息

存儲在.env文件中的環境變量可用於功能配置,但您不應將它們視為存儲敏感信息(如數據庫憑據或 API 密鑰)的安全方式。如果您將.env文件簽入源代碼管理,這一點尤其重要。

為了幫助您存儲敏感的配置信息,Cloud Functions for Firebase 與 Google Cloud Secret Manager集成。此加密服務安全地存儲配置值,同時仍允許在需要時從您的函數輕鬆訪問。

創建和使用秘密

要創建機密,請使用 Firebase CLI。

創建和使用秘密:

  1. 從本地項目目錄的根目錄運行以下命令:

    firebase functions:secrets:set SECRET_NAME

  2. 輸入SECRET_NAME的值。

    CLI 回顯一條成功消息並警告您必須部署函數才能使更改生效。

  3. 在部署之前,請確保您的函數代碼允許函數使用runWith參數訪問機密:

    exports.processPayment = functions
      // Make the secret available to this function
      .runWith({ secrets: ["SECRET_NAME"] })
      .onCall((data, context) => {
        const myBillingService = initializeBillingService(
          // reference the secret value
          process.env.SECRET_NAME
        );
        // Process the payment
      });
  4. 部署雲功能:

    firebase deploy --only functions

現在您將能夠像訪問任何其他環境變量一樣訪問它。相反,如果另一個未在runWith中指定秘密的函數嘗試訪問該秘密,它會收到一個未定義的值:

exports.anotherEndpoint = functions.https.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
});

部署您的函數後,它將可以訪問秘密值。只有在其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

對於accessdestroy命令,您可以提供可選的版本參數來管理特定版本。例如:

functions:secrets:access SECRET_NAME[@VERSION]

有關這些操作的更多信息,請將-h與命令一起傳遞以查看 CLI 幫助。

密文如何計費

Secret Manager 允許 6 個免費的活動密鑰版本。這意味著您每月可以在 Firebase 項目中免費獲得 6 個密文。

默認情況下,Firebase CLI 會嘗試在適當的時候自動銷毀未使用的密鑰版本,例如當您使用新版本的密鑰部署函數時。此外,您可以使用functions:secrets:destroyfunctions: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
行星=地球

觀眾=人類

觀眾=開發人員觀眾=當地人

在本地上下文中啟動時,模擬器加載環境變量,如下所示:

  $ 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的環境配置,則可以將現有配置遷移為環境變量( dotenv格式)。 Firebase CLI 提供了一個導出命令,該命令將目錄的.firebaserc文件中列出的每個別名或項目的配置(在下面的示例中為localdevprod )輸出為.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 ,如環境變量所示。

環境配置

firebase-functions v3.18.0發布環境變量支持之前,推薦使用functions.config()進行環境配置。這種方法仍然受支持,但我們建議所有新項目改用環境變量,因為它們更易於使用並提高代碼的可移植性。

使用 CLI 設置環境配置

要存儲環境數據,您可以在Firebase CLI中使用firebase functions:config:set命令。每個鍵都可以使用句點命名空間,將相關配置組合在一起。請記住,鍵中只接受小寫字符;不允許使用大寫字符。

例如,要存儲“某些服務”的客戶端 ID 和 API 密鑰,您可以運行:

firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"

檢索當前環境配置

要檢查項目的環境配置中當前存儲的內容,您可以使用firebase functions:config:get 。它會輸出類似這樣的 JSON:

{
  "someservice": {
    "key":"THE API KEY",
    "id":"THE CLIENT ID"
  }
}

此功能基於Google Cloud Runtime Configuration API

使用functions.config訪問函數中的環境配置

在保留的firebase命名空間下自動提供一些配置。通過functions.config()在運行的函數中提供環境配置。要使用上面的配置,您的代碼可能如下所示:

const functions = require('firebase-functions');
const request = require('request-promise');

exports.userCreated = functions.database.ref('/users/{id}').onWrite(event => {
  let email = event.data.child('email').val();

  return request({
    url: 'https://someservice.com/api/some/call',
    headers: {
      'X-Client-ID': functions.config().someservice.id,
      'Authorization': `Bearer ${functions.config().someservice.key}`
    },
    body: {email: email}
  });
});

使用環境配置來初始化模塊

某些 Node 模塊無需任何配置即可準備就緒。其他模塊需要額外配置才能正確初始化。我們建議您將此配置存儲在環境配置變量中,而不是對其進行硬編碼。這可以幫助您保持代碼的可移植性,讓您可以開源應用程序或輕鬆地在生產版本和暫存版本之間切換。

例如,要使用Slack Node SDK模塊,您可以這樣寫:

const functions = require('firebase-functions');
const IncomingWebhook = require('@slack/client').IncomingWebhook;
const webhook = new IncomingWebhook(functions.config().slack.url);

在部署之前,設置slack.url環境配置變量:

firebase functions:config:set slack.url=https://hooks.slack.com/services/XXX

其他環境命令

  • firebase functions:config:unset key1 key2從配置中刪除指定的鍵
  • firebase functions:config:clone --from <fromProject>將另一個項目的環境克隆到當前活動的項目中。

自動填充的環境變量

有一些環境變量會自動填充到函數運行時和本地模擬函數中。其中包括由 Google Cloud 填充的那些,以及特定於 Firebase 的環境變量:

process.env.FIREBASE_CONFIG :提供以下 Firebase 項目配置信息:

{
  databaseURL: 'https://databaseName.firebaseio.com',
  storageBucket: 'projectId.appspot.com',
  projectId: 'projectId'
}

當您不帶參數初始化 Firebase Admin SDK 時,會自動應用此配置。如果您正在用 JavaScript 編寫函數,請像這樣初始化:

const admin = require('firebase-admin');
admin.initializeApp();

如果您在 TypeScript 中編寫函數,請像這樣初始化:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import 'firebase-functions';
admin.initializeApp();

如果您需要使用服務帳戶憑據使用默認項目配置初始化 Admin SDK,您可以從文件加載憑據並將它們添加到FIREBASE_CONFIG ,如下所示:

serviceAccount = require('./serviceAccount.json');

const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);