2020-12-28
CloudFunctions for Firebaseの環境変数管理
CloudFunctions for Firebaseの環境変数はよくあるパターンとは異なり、
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
で実環境の環境変数を設定し、JSプログラムから取得する場合は
const functions = require('firebase-functions');
const SOME_SERVICE_ID = functions.config().someservice.id
のように取得する。
普通のパターンなら dotenv
等を使用して管理する所だが、違うパターンのため環境変数は以下のように管理するようにした。
使用するパッケージ
- config
- lodash/get
本番/ステージング環境では前述のように functions.config()
経由で環境変数を取得し、それ以外のエミュレータやテスト環境では、 config
パッケージを使用して管理・取得するようにした。
例えば、 config/test.json
に
{
"someservice": {
"key":"THE API KEY",
"id":"THE CLIENT ID"
}
}
のような設定ファイルを用意し、Node.jsプログラムでは以下のように取得している。
import * as functions from 'firebase-functions'
import config from '../../../../next-blog/config'
import get from 'lodash/get'
export const NODE_ENV = (() => {
const value = process.env.NODE_ENV ?? 'production'
if (value === 'production' || value === 'emulator' || value === 'test') {
return value
}
throw new Error('NODE_ENV must be production or emulator or test')
})()
const getConfig = () =>
NODE_ENV === 'production' ? functions.config() : config
const getEnvValue = (path: string) => {
const value = get(getConfig(), path)
if (value === undefined) {
throw new Error(`env ${path} is undefined`)
}
return value
}
export const SOME_SERVICE_KEY = getEnvValue('some_service.key')
export const SOME_SERVICE_ID = getEnvValue('some_service.id')
工夫したところは lodash/get
関数を使用してオブジェクトにアクセスしている箇所。環境変数は設定し忘れをすることが多く、その際にはできるだけ早く例外を吐いて落ちて欲しい。そのためには環境変数取得処理を共通化しないとコードが乱雑になってしまうが、 lodash/get
関数を使うことで共通化出来た。get(someObject, 'foo.bar.baz')
みたいに文字列で取得するキーを指定できる関数が欲しかった所 lodash/get
がまさにそれだった。
あとは config
パッケージは NODE_ENV
によって読み込む設定ファイルを変更するため、例えばテストの際は NODE_ENV=test jest
のようにすればOK。