設定環境


您通常需要為函式進行額外設定,例如 第三方 API 金鑰或可調整設定Cloud Functions 專用的 Firebase SDK 提供 內建的環境設定,方便您輕鬆儲存和擷取 決定專案的資料類型

選項有以下三種:

  • 參數化設定 (適用於多數情況)。這能提供強型別的環境 含有會在部署期間驗證的參數 不但能防止錯誤,還能簡化偵錯作業。
  • 環境變數的檔案型設定。採用這個方法時,您必須手動建立 dotenv 檔案進行載入 環境變數
  • 使用 Firebase CLI 的執行階段環境設定functions.config (僅限 Cloud Functions (第 1 代))。

在大多數情況下,建議您採用參數化設定。這個方法 可讓您在執行階段和部署期間使用設定值。 除非所有參數具備有效的值,否則部署作業會遭到封鎖。 反之,在部署時無法使用環境變數的設定 讓應用程式從可以最快做出回應的位置 回應使用者要求

參數化設定

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> 檔案新增至版本管控系統。

在全域範圍使用參數

部署期間,系統會在 每個參數都有實際值也就是說,在測試期間 全域範圍會導致部署失敗。如果您要使用 參數來初始化全域值,請使用初始化回呼 onInit()。此回呼會在實際執行任何函式之前執行, 沒有在部署期間呼叫,因此您可以透過安全的地方存取參數的 值。

  const { GoogleGenerativeAI } = require('@google/generative-ai');
  const { defineSecret } = require('firebase-functions/params');
  const { onInit } = require('firebase-functions/v1');

  const apiKey = defineSecret('GOOGLE_API_KEY');

  let genAI;
  onInit(() => {
    genAI = new GoogleGenerativeAI(apiKey.value());
  })

設定 CLI 行為

您可以使用用來控管 CLI 方式的 Options 物件來設定參數 會提示您輸入值下列範例將用來設定驗證 格式、提供簡易選項,以及 從 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:相關聯的即時資料庫執行個體網址 函式 (如果 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敬上 存取 API

如要以這種方式設定環境,請在專案中建立 .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=地球

AUDIENCE=人類

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 專案
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • 區域
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • 通訊埠
  • 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. 部署 Cloud Functions:

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

AUDIENCE=人類

AUDIENCE=Dev Humans AUDIENCE=當地人

在本機環境中啟動時,模擬器會載入環境 變數,如下所示:

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

Cloud Functions 模擬器中的密鑰和憑證

Cloud Functions 模擬器支援使用密鑰來 儲存及存取機密設定資訊。 根據預設,模擬器會嘗試使用 應用程式預設憑證。 模擬器在某些情況下 (例如 CI 環境) 可能會無法存取 存取所有 Secret 值。

與 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,如 升級至第 2 代

環境設定

firebase-functions v3.18.0 中發布對環境變數的支援之前,建議您採用 functions.config() 為 環境設定系統仍支援這個做法,但建議您 所有新專案都會改用環境變數,因為這類變數更加容易使用 並改善程式碼的可攜性

使用 CLI 完成環境設定

如要儲存環境資料,您可以使用 firebase functions:config:set Firebase CLI 中的指令。 每個鍵都可以使用半形句號來為相關群組建立命名空間 多個設定請注意,只有小寫字元 接受金鑰時不允許使用大寫字母。

舉例來說,若要儲存用戶端 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}
  });
});

使用環境設定初始化模組

部分節點模組已準備就緒,不需進行任何設定。其他模組需要額外 才能正確初始化建議您儲存這項設定 ,不必以硬式編碼方式寫入。這有助於 可以讓程式碼更容易使用 進而將原始碼的原始碼 或輕鬆切換正式版和測試版本。

舉例來說,如要使用 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);