設定環境


您通常需要為函式進行額外設定,例如 第三方 API 金鑰或可調整設定Cloud FunctionsFirebase SDK 提供內建環境設定,方便您為專案儲存及擷取這類資料。

您可以選擇下列任一選項:

  • 參數設定 (適用於大多數情況)。這能提供強型別的環境 含有會在部署期間驗證的參數 不但能防止錯誤,還能簡化偵錯作業。
  • 環境變數的檔案型設定。採用這個方法時,您必須手動建立 dotenv 檔案進行載入 環境變數

在大多數情況下,建議您採用參數化設定。這個方法 可讓您在執行階段和部署期間使用設定值。 除非所有參數具備有效的值,否則部署作業會遭到封鎖。 相反地,您無法在部署期間使用環境變數設定。

參數化設定

Cloud Functions for Firebase 提供介面,可在程式碼集中以宣告方式定義設定參數。這些參數的值是 在函式部署期間、設定部署和執行階段時 選項和執行期間也就是說,CLI 除非所有參數具備有效的值

如要在程式碼中定義參數,請按照下列模式操作:

const functions = require('firebase-functions/v1');
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 Projects
storage buckets"})

參數類型

參數化設定為參數值提供強大的輸入功能, 也支援 Cloud Secret Manager 的密鑰支援的類型如下:

  • 密鑰
  • 字串
  • 布林值
  • 整數
  • 浮點值

參數值和運算式

Firebase 會在部署時和函式執行期間評估參數。由於這種雙重環境,當出現上述情況時, 比較參數值,以及使用該值設定應用程式的執行階段選項時 函式。

如要將參數做為執行階段選項傳遞至函式,請直接傳遞參數:

const functions = require('firebase-functions/v1');
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/v1');
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/v1');
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 中的值的字串參數。密鑰參數會檢查 Cloud Secret Manager 中的存在性,並在部署期間以交互方式提示新密鑰的值,而非檢查本機 .env 檔案,並在缺少時將新值寫入檔案。

以這種方式定義的密鑰參數必須繫結至個別函式, 應具備下列存取權:

const functions = require('firebase-functions/v1');
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=Earth

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_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_SERVICE
  • K_REVISION
  • PORT
  • K_CONFIGURATION

儲存及存取機密設定資訊

儲存在 .env 檔案中的環境變數可用於函式 但我們不建議您以安全的方式儲存 例如資料庫憑證或 API 金鑰如果您將 .env 檔案存入原始碼控管,這點就格外重要。

為協助您儲存敏感設定資訊,Cloud Functions for FirebaseGoogle 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 變更需要您修改和/或重新部署相關函式。具體步驟包括:

  • 每當您為密鑰設定新值時,都必須重新部署參照該密鑰的所有函式,才能擷取最新值。
  • 如果您刪除 Secret,請確認所有已部署的函式都不會參照該 Secret。使用以下項目的密鑰值: 刪除作業就會失敗,且不會顯示相關通知。

以下是 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
PLANET=Earth

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 代

環境設定

使用 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/v1');
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/v1');
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/v1';
import * as admin from 'firebase-admin';
import 'firebase-functions/v1';
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);