見出し画像

GitHub ActionsでFirebase Remote Configの設定を更新する


はじめに


みなさん、お元気ですか。
SHIFT DAAE(ダーエ)グループ所属のsakuraiです。

弊社でFirebase Remote Configを利用したプロジェクトがあり、
今まではRemote Configの更新を手作業で行なっていましたが以下の課題が出てきました。

  • 毎回手作業で管理画面からファイルアップロードや更新を行いたくない。

  • Remote ConfigのテンプレートではJSON形式の値を利用する場合、エスケープされた文字列を操作するので編集しづらい

ということで、Remote Configの設定をGitHub Actionsで更新できるよう環境の整備を行いました。
実施した内容をサンプル化したものを記事に書きますので、お役に立てば幸いです。

前提条件

Remote Configを利用しているFirebaseプロジェクトを利用します。

Node.jsを利用します。

% node -v
v20.11.0
% npm -v
10.3.0

また、Firebase Admin SDKを利用しますので以下を参考にしてください。
https://firebase.google.com/docs/admin/setup?hl=ja

プロジェクトの作成


まずは、Firebase Remote Configの設定を管理するためのプロジェクトを作成します。

// ホームディレクトリに作成する
cd ~
mkdir sample_publish_remote_config
cd sample_publish_remote_config
touch package.json

package.jsonでfirebase-adminを追加しています。

{
  "name": "sample_publish_remote_config",
  "version": "0.0.0",
  "type": "module",
  "license": "UNLICENSED",
  "private": true,
  "dependencies": {
    "firebase-admin": "^12.0.0"
  }
}

Remote Config管理用テンプレートの作成


次にtemplatesディレクトリを作成し、Remote Configのテンプレートを格納します。
今回は、数値、文字列、JSONを管理することを想定したテンプレートにしてみました。
まず、Remote Configのテンプレートの形式は以下のJSONファイルの様になります。

# Remote Configのテンプレートサンプル
{
  "parameters": {
    "numberParam": {
      "defaultValue": {
        "value": "1"
      },
      "valueType": "NUMBER"
    },
    "textParam": {
      "defaultValue": {
        "value": "sampleText"
      },
      "valueType": "STRING"
    },
    "objectParam": {
      "defaultValue": {
        "value": "{\"version\":\"0.0.0\",\"url\":{\"example\":\"https://example.com/\"}}"
      },
      "valueType": "JSON"
    }
}

この場合、"objectParam"のJSONの値がエスケープされた文字列で管理されるので視認性が良くありません
変更時の事故を防ぐため、一手間加えてJSONの値は別ファイルで管理し、更新時にスクリプトで結合するようにしました
最終的に以下の構成でファイルを管理します。

# ./templates/remote_config.json
{
  "parameters": {
    "numberParam": {
      "defaultValue": {
        "value": "1"
      },
      "valueType": "NUMBER"
    },
    "textParam": {
      "defaultValue": {
        "value": "sampleText"
      },
      "valueType": "STRING"
    },
    "objectParam": {
      "defaultValue": {
        "value": "dummy"  // エスケープされたJSON値は視認性が良くないため別ファイルで管理する
      },
      "valueType": "JSON"
    }
  }
}
# ./templates/objectParam.json
{
  "version": "0.0.0",
  "url": {
    "example": "https://example.com/"
  }
}

objectParamの値をobjectParam.jsonファイルで管理することで視認性が良くなりました。
それでは次に公開用のスクリプトを作成します。

Remote Config公開用のスクリプトを作成する


Firebase Admin SDKを利用した公開用のスクリプトを作成します。
こちらの記事を参考にさせていただきました。

Firebase Remote Config をプログラム経由で更新する
https://zenn.dev/mono/articles/49e0e441af02d5c3b973

前章の通り、JSON形式の値は別ファイルで管理するので、dummyから別ファイルの値に置き換える処理を追加しています。

# publishRemoteConfig.js
import admin from 'firebase-admin'
import serviceAccount from './serviceAccountKey.json' assert { type: 'json' }
import * as fs from 'fs'
import * as util from 'util'

(async () => {

  admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
  });

  // Remote Configから現在の設定を取得
  const config = admin.remoteConfig();
  const currentTemplate = await config.getTemplate();

  // ファイルから設定を読み込む
  const templateJson = {
    ...JSON.parse(fs.readFileSync('./templates/remote_config.json', 'utf8')),
    etag: currentTemplate.etag,
  }

  // JSON形式の値は文字列に変換してセットする
  templateJson.parameters.objectParam.defaultValue.value = jsonString('./templates/objectParam.json');

  // Remote Config公開
  await config.publishTemplate(
    config.createTemplateFromJSON(JSON.stringify(templateJson))
  );

  console.log('Firebase Remote Config template published successfully!');
  console.log('--- Published Config ---');
  console.log(util.inspect(currentTemplate, { depth: null }))
})();

function jsonString(filePath) {
  const data = fs.readFileSync(filePath, 'utf8');
  const jsonString = JSON.stringify(JSON.parse(data));
  return jsonString;
}

serviceAccountKey.jsonはFirebaseプロジェクトの設定から新しい秘密鍵を生成してプロジェクト内に保存してください。

また誤ってリポジトリに登録されないよう**.gitignore**に追記します。

# .gitignore
node_modules/
serviceAccountKey.json

以下のコマンドでRemote Configの公開ができるようになりました!

cd ~/sample_publish_remote_config
npm install
node publishRemoteConfig.js

GitHub Actionsワークフローの作成


次にGitHub Actionsで実行するためにワークフローを作成します。

まずは先ほどダウンロードしたserviceAccountKey.jsonをbase64エンコードしてGitHubのリポジトリのSecretsに、SERVICE_ACCOUNT_KEYという名前で登録します。

// 出力された値をSERVICE_ACCOUNT_KEYという名前で登録します。
base64 -i serviceAccountKey.json

次に.github/workflowsディレクトリを作成しワークフローを定義します。

# .github/workflows/publish_remote_config.yaml
name: publish_remote_config

on:
  workflow_dispatch: 

jobs:
  publish-remote-config:
    name: Publish RemoteConfig
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: npm
          cache-dependency-path: './package-lock.json'

      # serviceAccountKey.jsonの生成
      - name: Import serviceAccountKey.json
        run:  echo -n ${{ secrets.SERVICE_ACCOUNT_KEY }} | base64 -d > ./serviceAccountKey.json

      - name: Run npm install
        run: npm install

      - name: Run node publishRemoteConfig.js
        run: node publishRemoteConfig.js

これで、GitHub Actionsを使用してFirebase Remote Configの設定を更新する準備が整いました!

おわりに


対応を実施することでRemote Config管理画面での操作が不要になったことも良かったのですが、JSON形式で管理しているRemote Configの設定の編集や変更差分の確認が楽になったことが一番効果的だと感じました。
またサンプルでは手動でGitHub Actionsを実行していますが、PRマージ時に自動的に更新を行なっても良いと思います。

最後までお読みいただきありがとうございました。

\DAAEマガジン/


執筆者プロフィール:sakurai
SHIFT DAAEグループ所属の開発エンジニアです。

\もっと身近にもっとリアルに!DAAE 公式 X/


お問合せはお気軽に

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/