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 密鑰或可調設置。 Firebase SDK for Cloud Functions 提供了內置的環境配置,讓您可以輕鬆地為您的項目存儲和檢索此類數據。

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

  • 參數化配置(推薦用於大多數場景)。這提供了具有在部署時驗證的參數的強類型環境配置,從而防止錯誤並簡化調試。
  • 基於文件的環境變量配置。使用這種方法,您可以手動創建一個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
PLANET=地球

觀眾=人類

觀眾=開發人類觀眾=刺激人類

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

$ 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_REGION
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • 港口
  • K_CONFIGURATION

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

存儲在.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命令,您可以提供可選的 version 參數來管理特定版本。例如:

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
PLANET=地球

觀眾=人類

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

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

  $ 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

請注意,在某些情況下,系統會提示您輸入前綴以重命名導出的環境變量鍵。這是因為並非所有配置都可以自動轉換,因為它們可能無效或可能是保留的環境變量 key

我們建議您在部署函數或將.env文件檢入源代碼控制之前仔細查看生成的.env文件的內容。如果任何值是敏感的並且不應洩露,請將它們從您的.env文件中刪除,並將它們安全地存儲在Secret Manager中。

您還需要更新函數代碼。任何使用functions.config的函數現在都需要使用process.env ,如環境變量所示。

環境配置

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

使用 CLI 設置環境配置

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

例如,要存儲“某些服務”的客戶端 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);