firebase deploy 周りの罠と対処法(その1)

Nuxt + Firebase でアプリケーションを構築する場合、firebase deploy のお世話になると思うのですがここをいろいろカスタムしようとするとハマりどころがいくつかあったのでまとめです。

同一プロジェクト内で複数の環境を作成する

複数環境を作成する場合のベストプラクティスはおそらくFirebase/GCPのプロジェクト自体を分けること、なのでしょうが、ただ新機能開発用のブランチと環境が欲しいなどの時にそこまでやっていられないというのがあると思います。
それでこれが firebase deploy を使ってできるかというとおそらくできません。
というのも firebase deploy でデプロイされる Cloud Run 関数の名前が server で決めうちになるためです。どうやってもここにデプロイされてしまうのでブランチごとに分けることができません。。。
調べるとできそうな雰囲気もあるのですが私は諦めました。

どうするか

「firebase deploy を使わない」です。
正確にはfunctionsだけfirebase deployの対象から外しgcloud functions delpoy でデプロイします。
ポイントは以下3点。

  1. gcloud コマンド
  2. firebase.json の記述
  3. firebase deploy のオプション
# 1. gloud コマンド。手動もしくは Github Actions に設定 (ブランチによる条件分岐等は割愛)
      // firebase deploy のpredeploy処理が無いのであらかじめビルドしておく
      - name: build
        run: npm run build --preset=firebase

      // mybranch-server というfunction名でデプロイする
      - name: deploy mybranch to mybranch-server function
        run: |
          if [[  ${{ github.ref }} == 'refs/heads/mybranch' ]]; then
            if gcloud functions deploy mybranch-server \
              --gen2 \
              --region asia-northeast1 \
              --runtime nodejs20 \
              --trigger-http \
              --allow-unauthenticated \
              --source .output/server \
              --entry-point server; then
              echo "gcloud deploy: Function Deployed successfully"
            else
              echo "gcloud deploy: Function Deployment failed"
              exit 1
            fi
          fi

# 2. firebase.json
  // functions にはもともとのエントリーのみ記載
  "functions": {
  ...
  }
  // hostingは配列形式にして追加
  "hosting": [
    {
      "target": "dev",
      "public": ".output/public",
      "cleanUrls": true,
      "rewrites": [
        {
          "source": "**",
          "function": "server"
        }
      ],
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
    },
    {
      "target": "mybranch", // 追加エントリー
      "public": ".output/public",
      "cleanUrls": true,
      // Cloud storage のバケットを作っておく
      "bucket": "mybranch-bucket",
      "rewrites": [
        {
          "source": "**",
          "function": "mybranch-server" // 追加するfunctionの名前
        }
      ],
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
    }
  ]
}

# 3. firebase deploy コマンドは mybranchのhostingのみデプロイします。
$ firebase deploy --project={your project} --only hosting:mybranch

以上です。
firebase deploy を使った場合とは厳密に同じでは無い可能性はあるのでそこだけは注意してください。