TestCrew
Firebase・Android設定

Firebaseで開発環境と本番環境を分ける方法|複数プロジェクトとflavor

Firebaseの開発環境と本番環境を分離する方法を解説。複数Firebaseプロジェクト、Android product flavor、google-services.json、FlutterFire、CI設定を紹介します。

公開
2026年8月2日
更新
2026年8月2日
公式情報確認
2026年8月3日
Firebaseの開発環境と本番環境の分離構成
この記事の目次

Firebaseを使うアプリでは、開発中の操作が本番データへ影響しないよう、開発環境と本番環境を分離します。

推奨する基本構成は、Firebaseプロジェクト自体を分け、Androidのproduct flavorごとに接続先を固定する方法です。

Firebaseの開発・本番環境を分離

推奨構成

環境applicationIdFirebase project_id表示名
開発com.example.app.devexample-app-devExample Dev
本番com.example.appexample-app-prodExample

この構成なら、同じ端末へ開発版と本番版を同時にインストールできます。

なぜFirebaseプロジェクトを分けるのか

一つのFirebaseプロジェクトへ開発版と本番版のAndroidアプリを登録しても、Firestore、Authentication、Storageなどのバックエンドは同じプロジェクトです。

本番データを隔離するには、プロジェクトを分けます。

分離できるもの

  • Authenticationユーザー
  • Firestoreデータ
  • Realtime Database
  • Cloud Storage
  • Cloud Functions
  • Security Rules
  • Remote Config
  • Cloud Messaging
  • Crashlytics
  • Analytics
  • App Check

ステップ1:Firebaseプロジェクトを作成

例:

example-app-dev
example-app-prod

example-appexample-app-2のような曖昧な名前は避け、コンソールやCLIで見ただけで環境を判断できる名前にします。

ステップ2:Androidアプリを登録

開発用プロジェクト:

com.example.app.dev

本番用プロジェクト:

com.example.app

各Firebaseプロジェクトから対応するgoogle-services.jsonを取得します。

ステップ3:product flavorを設定

Kotlin DSL:

android {
    namespace = "com.example.app"

    defaultConfig {
        applicationId = "com.example.app"
    }

    flavorDimensions += "environment"

    productFlavors {
        create("development") {
            dimension = "environment"
            applicationIdSuffix = ".dev"
            versionNameSuffix = "-dev"
            resValue("string", "app_name", "Example Dev")
        }

        create("production") {
            dimension = "environment"
            resValue("string", "app_name", "Example")
        }
    }
}

生成されるvariant:

developmentDebug
developmentRelease
productionDebug
productionRelease

ステップ4:JSONをflavor別に配置

app/src/development/google-services.json
app/src/production/google-services.json

開発ファイル:

{
  "project_info": {
    "project_id": "example-app-dev"
  }
}

本番ファイル:

{
  "project_info": {
    "project_id": "example-app-prod"
  }
}

ルートのapp/google-services.jsonへ本番用ファイルだけを置くと、development側の配置漏れに気づきにくくなります。環境別運用では専用ディレクトリへ明示します。

ステップ5:表示名とアイコンを分ける

開発版を本番版と見間違えないようにします。

  • 表示名にDevを付ける
  • 開発版アイコンへDEVバッジを付ける
  • 画面に環境表示を出す
  • 開発版だけデバッグメニューを有効にする

本番版で環境名を常時表示する必要はありません。

接続先をログで確認する

Android:

val app = FirebaseApp.getInstance()
Log.d("FirebaseEnv", "project=${app.options.projectId}")

Flutter:

final app = Firebase.app();
debugPrint('project=${app.options.projectId}');

期待値:

development → example-app-dev
production  → example-app-prod

Flutterで環境を分ける

ディレクトリ例:

lib/
├── bootstrap.dart
├── main_development.dart
├── main_production.dart
├── firebase_options_development.dart
└── firebase_options_production.dart

android/app/src/
├── development/google-services.json
└── production/google-services.json

開発用:

flutterfire configure \
  --project=example-app-dev \
  --android-package-name=com.example.app.dev \
  --out=lib/firebase_options_development.dart

本番用:

flutterfire configure \
  --project=example-app-prod \
  --android-package-name=com.example.app \
  --out=lib/firebase_options_production.dart

共通bootstrap

Future<void> bootstrap({
  required FirebaseOptions options,
}) async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: options);
  runApp(const MyApp());
}

開発版を起動

flutter run \
  --flavor development \
  --target lib/main_development.dart

本番AAB

flutter build appbundle \
  --flavor production \
  --target lib/main_production.dart

Firebase CLIを分ける

プロジェクトエイリアスを追加します。

firebase use --add

.firebaserc

{
  "projects": {
    "dev": "example-app-dev",
    "prod": "example-app-prod"
  }
}

デプロイ時は対象を明示します。

firebase deploy --project=dev
firebase deploy --project=prod

本番デプロイで現在のactive projectだけに依存しない方が安全です。

CIでの検証

本番ビルド前に次を検証します。

  • flavorがproduction
  • applicationIdがcom.example.app
  • JSONのproject_idがexample-app-prod
  • 本番用署名設定
  • 本番用API・Webhook

JSONの確認例:

python - <<'PY'
import json
from pathlib import Path

path = Path('android/app/src/production/google-services.json')
data = json.loads(path.read_text())
actual = data['project_info']['project_id']
expected = 'example-app-prod'
if actual != expected:
    raise SystemExit(f'Wrong Firebase project: {actual}')
print(actual)
PY

Googleログイン・SHAも環境別

開発版:

  • package:com.example.app.dev
  • debug SHA-1・SHA-256

本番版:

  • package:com.example.app
  • Google Playアプリ署名鍵のSHA-1・SHA-256

各Firebaseプロジェクトの正しいAndroidアプリへ登録します。

Security Rulesも別管理

開発プロジェクトの緩いRulesを本番へ誤デプロイしないようにします。

本番では次を確認します。

  • 認証必須
  • 所有者チェック
  • データ形式
  • ロール
  • Storageパス
  • App Check
  • インデックス

構成ファイルを秘密にすることだけではデータを保護できません。

Local Emulator Suiteとの使い分け

ローカル単体・結合テスト
→ Emulator Suite

実機・共有テスト
→ 開発Firebaseプロジェクト

Google Play製品版
→ 本番Firebaseプロジェクト

エミュレータで確認できる処理は、本番クラウドへ接続せずに試します。

避けたい運用

  • 実行中のスイッチで開発・本番を切り替える
  • 本番JSONをアプリモジュール直下へ共通配置
  • Dart側だけ切り替えてネイティブ設定を共通にする
  • 開発版と本番版を同じ表示名・アイコンにする
  • CLIのactive projectだけを信頼する
  • 開発用の緩いRulesを本番へコピーする

まとめ

安全な環境分離は次のセットで行います。

product flavor
applicationId
Firebase project_id
google-services.json
FirebaseOptions
署名・SHA
CLIデプロイ先

本番ビルド前に、flavor・applicationId・project_idの3点を自動検証すると、誤接続を大きく減らせます。

一次情報

公式参考資料

Google PlayやFirebaseの画面・要件は変更される場合があります。公開作業の前に、リンク先の最新情報も確認してください。

Analytics設定

TestCrewは、Webサイトの改善のためGoogle LLCが提供するGoogle Analyticsを使用します。利用の可否を変更でき、変更後はこのページの以後の計測と次回以降の訪問に反映されます。 プライバシーポリシーを見る