Firebase Summit で発表されたすべての情報をご覧ください。Firebase を使用してアプリ開発を加速し、自信を持ってアプリを実行する方法を紹介しています。詳細

環境を構成します

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

多くの場合、サードパーティの API キーや調整可能な設定など、関数の追加構成が必要になります。 Firebase SDK for Cloud Functions には組み込みの環境構成が用意されており、プロジェクトでこの種のデータを簡単に保存および取得できます。

次の 3 つのオプションから選択できます。

  • パラメーター化された構成(ほとんどのシナリオで推奨)。これにより、デプロイ時に検証されるパラメーターを使用して厳密に型指定された環境構成が提供されるため、エラーが防止され、デバッグが簡素化されます。
  • 環境変数のファイルベースの構成。このアプローチでは、環境変数をロードするための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 の動作を構成する

パラメータは、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サブパッケージから利用できる 3 つの定義済みパラメーターを提供します。

  • projectId — 関数が実行されている Cloud プロジェクト。
  • databaseUrl — 関数に関連付けられた Realtime Database インスタンスの 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 は、 .envファイルで指定された環境変数をアプリケーション ランタイムに読み込むためのdotenvファイル形式をサポートしています。デプロイが完了すると、環境変数は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ファイル (存在する場合) の環境変数は、デプロイされたすべての関数に含まれます。

たとえば、プロジェクトには、開発用と本番用でわずかに異なる値を含む次の 3 つのファイルを含めることができます。

.env .env.dev .env.prod
PLANET=地球

AUDIENCE=人間

AUDIENCE=開発者AUDIENCE=製品人間

これらの個別のファイルに値がある場合、関数と共にデプロイされる環境変数のセットは、ターゲット プロジェクトによって異なります。

$ 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. 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

accessコマンドとdestroyコマンドの場合、オプションの version パラメータを指定して、特定のバージョンを管理できます。例えば:

functions:secrets:access SECRET_NAME[@VERSION]

これらの操作の詳細については、CLI ヘルプを表示するコマンドで-hを渡します。

シークレットの課金方法

Secret Manager では、6 つのアクティブなシークレットバージョンを無料で使用できます。これは、Firebase プロジェクトで 1 か月あたり 6 つのシークレットを無料で使用できることを意味します。

デフォルトでは、Firebase CLI は、シークレットの新しいバージョンで関数をデプロイする場合など、必要に応じて未使用のシークレット バージョンを自動的に破棄しようとします。また、 functions:secrets:destroyおよびfunctions:secrets:pruneを使用して、未使用のシークレットを積極的にクリーンアップできます。

Secret Manager では、1 つのシークレットに対して 10,000 回の請求されない月間アクセス操作が許可されます。関数インスタンスは、コールド スタートするたびにrunWithパラメータで指定されたシークレットのみを読み取ります。多くの関数インスタンスが多くのシークレットを読み取る場合、プロジェクトがこの許容量を超える可能性があり、その時点で 10,000 アクセス操作ごとに 0.03 USD が請求されます。

詳細については、 Secret Manager の料金を参照してください。

エミュレータのサポート

dotenv を使用した環境構成は、ローカルのCloud Functions エミュレーターと相互運用できるように設計されています。

ローカルの Cloud Functions エミュレーターを使用する場合、 .env.localファイルを設定することで、プロジェクトの環境変数をオーバーライドできます。 .env.localの内容は、 .envおよびプロジェクト固有の.envファイルよりも優先されます。

たとえば、プロジェクトには、開発用とローカル テスト用にわずかに異なる値を含む次の 3 つのファイルを含めることができます。

.env .env.dev .env.local
PLANET=地球

AUDIENCE=人間

AUDIENCE=開発者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 環境などの特定の状況では、権限の制限により、エミュレーターがシークレット値にアクセスできない場合があります。

環境変数に対する Cloud Functions エミュレーターのサポートと同様に、 .secret.localファイルをセットアップすることでシークレット値をオーバーライドできます。これにより、特にシークレット値にアクセスできない場合に、関数をローカルで簡単にテストできます。

環境構成からの移行

functions.configで環境構成を使用していた場合は、既存の構成を環境変数として ( dotenv形式で) 移行できます。 Firebase CLI は、ディレクトリの.firebasercファイル (以下の例ではlocaldev 、およびprod ) にリストされている各エイリアスまたはプロジェクトの構成を.envファイルとして出力する export コマンドを提供します。

移行するには、 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 CLIfirebase functions:config:setコマンドを使用できます。各キーは、ピリオドを使用して名前空間を指定し、関連する構成をグループ化できます。キーには小文字のみを使用できることに注意してください。大文字は使用できません。

たとえば、「Some Service」のクライアント 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);