設���環境


您通常需要為函式進行額外設定,例如 第三方 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);