柔軟に firebase admin を初期化する

thumbnail

毎回やり方を調べている気がするシリーズです。

firebase-admin を初期化する際、サーバーに Firebase Admin SDK を追加する を見ると、

var admin = require("firebase-admin");
var app = admin.initializeApp();

や、

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
});

として初期化されています。

しかし、この初期化方法だと困ることがあります。

例えば前者では、initializeApp の引数がなくこれはdefault service accountが読み込まれる GCP 上でしか動作しないコードです。 そして後者は予め環境変数GOOGLE_APPLICATION_CREDENTIALSにサービスアカウント情報を持った json ファイルへのパスを指定しておく必要があり、GitHub への PUSH をトリガーに Vercel などにデプロイする時には実現しづらい方法だったりします。(使用する PaaS によっては credential 情報を.git で管理する必要があるから)

initializeApp に認証情報を渡すことで初期化する。

そこで GCP 以外の PaaS にデプロイする方法を紹介します。

admin.initializeAppCredential を渡せば初期化できるので、それを作って渡すと認証を通せます。 つまりサービスアカウント情報が書かれた json ファイルに書かれている内容をそのまま渡せば良いです。

そして、その Credential は certから作れます。

const cert = {
  projectId: process.env.FIREBASE_PROJECT_ID,
  clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
  privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, "\n"),
};
admin.initializeApp({
  credential: admin.credential.cert(cert),
});

firebase のサービスアカウントの認証情報は projectId, clientEmail, privateKey 以外にもたくさんありますが、 cert が受け取る ServiceAccountは、projectId, clientEmail, privateKey で構成されているのでこの 3 つだけ渡してください。

replace 以下はエスケープ避けを回避するための処理です。

FYI: https://stackoverflow.com/questions/50299329/node-js-firebase-service-account-private-key-wont-parse

まとめ

  • firebase admin を使うためには admin.initializeApp() を実行する必要がある
  • GCP 以外にデプロイ・key file をデプロイ環境に含めない場合は、CredentialinitializeApp に渡して初期化
  • Credentialadmin.credential.cert に projectId, clientEmail, privateKey を渡すと作れる。

参考文献