Firebase開発をしていると、開発環境と本番環境の管理が煩雑になりがちです。最初はコンソールでポチポチ設定していたものの、「あれ?開発と本番で設定が違う…」「デプロイのたびにコンソール操作するの面倒…」と感じることが増えてきました。
今回は、手動のコンソール操作から完全自動化まで、実際の開発体験を交えて環境統一の方法を紹介します。
📱 対象プロジェクト
Firebase Functions + Firestore + Storage + Hosting + Extensions を使ったクイズアプリ
Firebase開発で環境を分ける場合、開発用と本番用で別々のFirebaseプロジェクトを作るのが一般的です。しかし、これが意外と管理が大変なんです。
😅 よくある問題
「開発環境で動いてたのに本番で動かない…」
「あれ?Firestoreのルール設定、本番に反映し忘れた」
「Extensionsの設定、手動で両方に設定するの忘れそう…」
手動でのコンソール操作は楽ですが、環境が増えるほど管理が困難になります。設定の差異、デプロイミス、属人化など、様々な問題が発生しがちです。
最初は開発環境でコンソールで直接
開発初期は、Firebase Consoleでの手動設定が一番楽です。
// 開発中の典型的な流れ
1. Firebase Console でプロジェクト作成
2. Authentication で Google ログイン有効化
3. Firestore でデータベース作成
4. Storage でバケット作成
5. Functions をコンソールからデプロイ
この段階では全てが順調です。コンソールの UI は直感的で、設定も簡単。「Firebase最高!」と思える瞬間です。
本番環境への手動複製で問題発生
しかし、本番環境を作る段階で問題が見えてきます。
// 本番環境作成時の作業
1. 新しいFirebaseプロジェクト作成
2. 開発環境と同じ設定を手動で再現
3. Firestoreのルールをコピペ
4. Storageのルールもコピペ
5. Extensionsも手動でインストール
💸 実際にあった問題
「本番環境のFirestoreルール設定し忘れて、セキュリティホールが…」
「Extensionsの環境変数、開発と本番で微妙に違ってた」
「どっちが正しい設定だっけ?」
手動複製は確実にミスが発生します。特に設定項目が多くなるほど、見落としが増えていきます。
Firebase SDKで設定管理
この問題を解決するのが、Firebase CLI を使った設定ファイル管理です。
既存設定のエクスポート
まず、手動で作った設定をファイルに落とし込みます。
# プロジェクトの初期化
firebase init
# Firestoreルールのエクスポート
firebase firestore:rules get > firestore.rules
# インデックス設定のエクスポート
firebase firestore:indexes > firestore.indexes.json
# Storageルールのエクスポート
firebase storage:rules get > storage.rules
これで、コンソールで設定した内容がファイルとして保存されます。
設定ファイルの Git 管理
エクスポートした設定ファイルを Git で管理することで、以下のメリットが得られます。
- バージョン管理: 設定変更の履歴が残る
- 差分確認: 何が変わったか一目瞭然
- ロールバック: 問題があれば前の状態に戻せる
- チーム共有: 設定をチーム全体で共有
# 設定ファイルをGitで管理
git add firebase.json firestore.rules storage.rules
git commit -m "Add Firebase configuration files"
統一デプロイの実現
設定ファイル化により、コマンド一つで全ての設定をデプロイできるようになります。
# 開発環境へデプロイ
firebase use development
firebase deploy
# 本番環境へデプロイ
firebase use production
firebase deploy
同じ設定ファイルを使うため、環境間の差異が発生しません。
🎉 劇的な改善
「設定ミスがなくなった!」
「デプロイが一瞬で終わる」
「新しい環境も簡単に作れる」
何が統一できるか?
Firebase CLI による設定管理で、以下の要素を完全に統一できます。
Cloud Functions
// functions/index.js
const admin = require("firebase-admin");
admin.initializeApp();
// 関数の実装は同一コードで両環境にデプロイ
// functions/package.json
{
"name": "functions",
"dependencies": {
"firebase-admin": "^11.11.1",
"firebase-functions": "^4.4.1"
}
}
統一される要素:
- 関数のコード
- 依存関係(package.json)
- Node.js バージョン
- ESLint 設定
Firestore
// firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /quiz/{quizId} {
allow read: if true;
allow write: if request.auth != null;
}
}
}
// firestore.indexes.json
{
"indexes": [
{
"collectionGroup": "quiz",
"queryScope": "COLLECTION",
"fields": [
{"fieldPath": "category", "order": "ASCENDING"},
{"fieldPath": "createdAt", "order": "DESCENDING"}
]
}
]
}
統一される要素:
- セキュリティルール
- 複合インデックス設定
- データベース構造
Cloud Storage
// storage.rules
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /quiz_images/{imageId} {
allow read: if true;
allow write: if request.auth != null;
}
}
}
統一される要素:
- アクセス制御ルール
- ファイル構造
- セキュリティポリシー
Hosting
// firebase.json (hosting部分)
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
統一される要素:
- 静的ファイルの配置
- リダイレクト設定
- キャッシュ設定
Extensions
// firebase.json (extensions部分)
{
"extensions": {
"delete-user-data": "firebase/delete-user-data@0.1.19"
}
}
# extensions/delete-user-data.env
AUTO_DISCOVERY_SEARCH_DEPTH=3
AUTO_DISCOVERY_SEARCH_FIELDS=id,uid,userId
CLOUD_STORAGE_BUCKET=${param:PROJECT_ID}.appspot.com
ENABLE_AUTO_DISCOVERY=yes
FIRESTORE_DELETE_MODE=recursive
統一される要素:
- 拡張機能のバージョン
- 環境変数設定
- 機能の有効/無効
💡 重要なポイント
Extensions もfirebase deployで自動インストールされます。コンソール操作は一切不要!
プロジェクト全体設定
// firebase.json
{
"functions": {
"source": "functions",
"predeploy": ["npm --prefix \"$RESOURCE_DIR\" run lint"]
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules"
},
"hosting": {
"public": "public"
},
"extensions": {
"delete-user-data": "firebase/delete-user-data@0.1.19"
}
}
// .firebaserc
{
"projects": {
"development": "quzishare",
"production": "quizsharerelease"
}
}
この設定により、firebase use development や firebase use production で簡単に環境を切り替えられます。
GitHub Actions で自動デプロイ
設定ファイル管理により個人開発での問題は解決しましたが、チーム開発ではさらなる自動化が有効です。
ブランチベースの環境分離
# .github/workflows/firebase_dev_deploy.yml
name: Deploy to Dev Firebase
on:
push:
branches: [dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/deploy
with:
project_id: quzishare
firebase_token: ${{ secrets.FIREBASE_TOKEN }}
# .github/workflows/firebase_release_deploy.yml
name: Deploy to Release Firebase
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/deploy
with:
project_id: quizsharerelease
firebase_token: ${{ secrets.FIREBASE_TOKEN }}
カスタム Action の活用
# .github/actions/deploy/action.yml
name: 'firebase deploy'
inputs:
project_id:
required: true
firebase_token:
required: true
runs:
using: "composite"
steps:
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Firebase CLI
run: npm install -g firebase-tools
shell: bash
- name: Install Functions dependencies
run: |
cd functions
npm install
shell: bash
- name: Deploy to Firebase
run: firebase deploy --token ${{ inputs.firebase_token }} --project ${{ inputs.project_id }}
shell: bash
完全自動化の恩恵
- ヒューマンエラー排除: 手動デプロイミスがゼロに
- デプロイ履歴: GitHub で全ての変更を追跡
- ロールバック簡単: Git revert でインフラも戻る
- チーム開発効率化: 誰でも同じ手順でデプロイ
- 新メンバー対応: 環境構築が自動化
🚀 開発体験の向上
「コードをプッシュするだけで本番反映」
「環境差異を心配する必要がない」
「新しい機能追加に集中できる」
チーム開発での価値
個人開発なら Firebase CLI だけでも十分ですが、チーム開発では GitHub Actions の価値が大きくなります。
- 属人化防止: 特定の人だけがデプロイできる状況を回避
- 品質保証: ESLint や テストを自動実行
- 承認フロー: Pull Request ベースでのレビュー
- 通知機能: Slack 連携でデプロイ状況を共有
まとめ
Firebase 開発における環境統一は、段階的に進化させることができます。
- 手動設定: 開発初期は楽だが、環境が増えると破綻
- 設定ファイル管理: Firebase CLI で大幅改善、個人開発なら十分
- CI/CD 自動化: チーム開発では必須、開発効率が劇的向上
特に重要なのは、全ての設定をコードとして管理することです。Functions、Firestore、Storage、Extensions まで、全てが統一された環境で動作します。
💡 個人的な結論
– 個人開発: Firebase CLI での設定管理は必須
– チーム開発: GitHub Actions での自動化まで実装
– コンソール操作: 緊急時以外は使わない
最初の設定は少し手間ですが、長期的な開発効率は大幅に向上します。
これから Firebase 開発を始める方、環境管理で悩んでいる方の参考になれば幸いです。
この記事は実際の開発体験を基に書いています。プロジェクトの規模や要件によって最適解は変わるので、あくまで一つの事例として参考にしてください。



コメント