📌 はじめに
Flutter アプリに Firebase を導入し、開発環境(staging)と本番環境(production)を分ける ための手順を備忘も兼ねてまとめました。
内容
- Firebase を staging(開発用)と production(本番用)に分ける
-
flutterfire_cli
を使用した Firebase 設定 -
GoogleService-Info
の環境ごとの管理 - 実機ビルド手順
1️⃣ Firebase プロジェクトの作成
Firebase で staging(開発用)と production(本番用)を分けるため、2 つの Firebase プロジェクト を作成します。
環境 | Firebase プロジェクト ID |
---|---|
開発環境 | {任意のプロジェクトID}-staging |
本番環境 | {任意のプロジェクトID}-production |
※APP名-stagingなど分かりやすいプロジェクト名が望ましいです。
2️⃣ flutterfire_cli
のインストール
Flutter アプリと Firebase を連携するために、flutterfire_cli
を使用します。
dart pub global activate flutterfire_cli
パスが通っていない場合は、.zshrc
/ .bashrc
に以下を追加して適用
export PATH="$PATH":"$HOME/.pub-cache/bin"
source ~/.zshrc # または source ~/.bashrc
3️⃣ Firebase 設定ファイルの生成
Firebase の GoogleService-Info.plist
、google-services.json
、firebase_options.dart
を 環境ごとに生成 し、同時にFirebaseプロジェクトにアプリを登録します。
各設定ファイルの役割は下記です。
ファイル | 役割 | 使われる場所 | プラットフォーム |
---|---|---|---|
GoogleService-Info.plist |
iOS 用 Firebase 設定 | iOS SDK (firebase_auth , firebase_core など) |
iOS |
google-services.json |
Android 用 Firebase 設定 | Android SDK (firebase_auth , firebase_core など) |
Android |
firebase_options.dart |
Flutter アプリの Firebase 設定 | Flutter (firebase_core ) |
Flutter 共通 |
📌 Staging 用(開発環境)
flutterfire configure --project={プロジェクト名}-staging \
--out=lib/firebase_options_staging.dart \
--ios-bundle-id={任意のbundleID}.staging \
--android-package-name={任意のパッケージ名}.staging
開発環境用に下記の設定ファイルが作成されます。
ios/Runner/GoogleService-Info.plist
android/app/google-services.json
lib/firebase_options_staging.dart
そのまま続けて本番環境用のコマンドを実行するとgoogle-services.json
、GoogleService-Info.plist
が本番環境用に上書きされてしまうので、その前にiOSはstaging用としてリネーム、Androidはディレクトリを作成して移動します。
※firebase_options.dart
はコマンド実行時に開発環境用としてファイル名を指定しているので問題なし
mv ios/Runner/GoogleService-Info.plist ios/Runner/GoogleService-Info-staging.plist
mkdir android/app/src/staging
mv android/app/google-services.json android/app/src/staging/google-services.json
📌 Production 用(本番環境)
flutterfire configure --project={プロジェクト名}-production \
--out=lib/firebase_options_production.dart \
--ios-bundle-id={任意のbundleID} \
--android-package-name={任意のパッケージ名}
本番環境用に下記の設定ファイルが作成されます。
ios/Runner/GoogleService-Info.plist
android/app/google-services.json
lib/firebase_options_production.dart
iOSはproduction用としてリネーム、Androidはディレクトリを作成して移動します
mv ios/Runner/GoogleService-Info.plist ios/Runner/GoogleService-Info-production.plist
mkdir android/app/src/production
mv android/app/google-services.json android/app/src/production/google-services.json
Tips:
設定ファイルを別環境のもので上書きしてしまった場合でも、Firebaseコンソール上から直接ダウンロードすることが可能です。または、もう一度コマンドを実行すれば再生成されます。
1.Firebaseコンソール にアクセス。
2.Firebase にログインし、対象のプロジェクトを開く。
3.左側のナビゲーションメニューから「⚙️ プロジェクトの設定」をクリック。
4.「アプリの設定」セクションに移動。
5.該当のアプリを選択。
6.「GoogleService-Info.plist をダウンロード」ボタンをクリック。
4️⃣ iOSの環境設定管理
iOS では GoogleService-Info.plist
を環境ごとに適用する必要があります。
📌 Info.plist
に以下を追加
Xcodeを起動し、Info.plistを開くか、XMLに直接記載します。
Xcode を開く
open ios/Runner.xcworkspace
Info.plistのCFBundleDisplayNameについて、アプリ名も環境別に分けるように修正します。
XMLに直接記載する場合は下記を記載
<key>CFBundleDisplayName</key>
<string>$(DISPLAY_NAME)</string>
📌 デバッグとリリースでアプリを分けるための設定
ios/Flutter/Debug.xcconfig と ios/Flutter/Release.xcconfig ファイルを編集または作成します。
#include "Generated.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER={任意のbundleID}.staging
DISPLAY_NAME={アプリ名}
#include "Generated.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER={任意のbundleID}
DISPLAY_NAME={アプリ名 STG}
「Target」>「Runner」 > 「Build Settings」タブで「Product Bundle Identifier」を「$(PRODUCT_BUNDLE_IDENTIFIER)」に設定
その他、com.example.xxxxの箇所を設定するbundleIDで置換します。
📌 Xcodeのビルドスクリプトを追加
stagingでは「GoogleService-Info-staging.plist」Productionでは「GoogleService-Info-production.plist」が使われるように設定をしていきます。
1.Xcodeを開く(ios/Runner.xcworkspace)
2.Runnerプロジェクトを選択
3.TARGETS > Runner > Build Phases を選択
4.「Run Script」に下記を追記
#!/bin/sh
# デバッグ出力を有効化
set -x
echo "Starting Firebase configuration script..."
# 初期設定ファイルの作成(スクリプトの最初で実行)
cp "${PROJECT_DIR}/Runner/GoogleService-Info-staging.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
# PRODUCTION の値を .xcconfig から取得
PRODUCTION_ENV=$(echo "$DART_DEFINES" | base64 -d | grep -E '^PRODUCTION=' | cut -d '=' -f2)
echo "Found PRODUCTION_ENV value: ${PRODUCTION_ENV}"
# デバッグ用の出力
echo "Raw DART_DEFINES: $DART_DEFINES"
echo "Decoded DART_DEFINES: $(echo "$DART_DEFINES" | base64 -d)"
# 値が空の場合のデフォルト値設定
if [ -z "$PRODUCTION_ENV" ]; then
PRODUCTION_ENV="false"
echo "PRODUCTION_ENV is empty, using default value: false"
fi
# 環境に応じて適切な設定ファイルをコピー
if [ "$PRODUCTION_ENV" == "true" ]; then
echo "Using Production Firebase configuration"
cp "${PROJECT_DIR}/Runner/GoogleService-Info-production.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
else
echo "Using Staging Firebase configuration"
cp "${PROJECT_DIR}/Runner/GoogleService-Info-staging.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
fi
# コピー結果の確認
if [ ! -f "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ]; then
echo "Error: Failed to copy GoogleService-Info.plist"
exit 1
fi
echo "Firebase configuration script completed successfully"
5️⃣ Androidの環境設定管理
Android では google-services.json
を環境ごとに適用するため、フレーバー設定を行います。
📌 android/app/build.gradle
を編集
androidの下にフレーバー設定を追加します。
android {
flavorDimensions "default"
productFlavors {
staging {
applicationId "{任意のパッケージ名}.staging"
// 必要に応じて他の設定も追加
resValue "string", "app_name", "{アプリ名} STG"
}
production {
applicationId "{任意のパッケージ名}"
// 必要に応じて他の設定も追加
resValue "string", "app_name", "{アプリ名}"
}
}
}
6️⃣ Firebase の初期化
Firebase関連の必要なパッケージを追加します。
dependencies:
flutter:
sdk: flutter
firebase_core: ^2.27.1
Firebase の環境を firebase_options_staging.dart(開発環境用)と
firebase_options_production.dart(本番環境用)で切り替えられるように設定します。
📌 main.dart
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options_staging.dart' as staging;
import 'firebase_options_production.dart' as prod;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 🔹 環境(開発・本番)を判定
const isProduction = bool.fromEnvironment('PRODUCTION', defaultValue: false);
// Firebase の初期化
await Firebase.initializeApp(
options: isProduction
? prod.DefaultFirebaseOptions.currentPlatform
: staging.DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
7️⃣ 実機ビルドの準備
📌 iPhone 実機を認識
Xcodeでプロジェクトを開くか下記コマンドを実行
open ios/Runner.xcworkspace
-
Runner
を選択 →Signing & Capabilities
タブ -
Team
を設定(Apple ID を登録) - 開発用プロビジョニングプロファイル を設定
📌 Android 実機を認識
- 端末のUSBデバッグ を有効にする
- 実機の 設定 → 端末情報 → ビルド番号を7回タップ(開発者オプションを有効化)
- 開発者オプション から USBデバッグ を有効にする
8️⃣ Debug で実機ビルド
端末に開発アプリをインストールするためのコマンドは下記です。
🔹 iOS
開発環境(Staging)
flutter run --dart-define=PRODUCTION=false
本番環境(Production)
flutter run --dart-define=PRODUCTION=true
※--debugをつけなくてもDebugビルドになります。
ビルド時に下記エラーが出る場合はflutter cleanやclean build folderを試して下さい。
Could not build the precompiled application for the device.
Error (Xcode): Build input file cannot be found: 'ios/Runner/GoogleService-Info.plist'.
Did you forget to declare this file as an output of a script phase or custom build rule which produces it?
🔹 Android
開発環境(Staging)
flutter run --flavor staging --dart-define=PRODUCTION=false
本番環境(Production)
flutter run --flavor production --dart-define=PRODUCTION=true
9️⃣ Release ビルド & インストール
🔹 iOS
実機に Release ビルドをインストール
開発環境(Staging)
flutter run --dart-define=PRODUCTION=false --release
または
flutter build ios --dart-define=PRODUCTION=false --release
flutter install
本番環境(Production)
flutter run --dart-define=PRODUCTION=true --release
または
flutter build ios --dart-define=PRODUCTION=true --release
flutter install
TestFlight / App Store にアップロードする場合
flutter build ipa --dart-define=PRODUCTION=true --release
上記を実行し、作成されたipaをTransporterでアップロード。
※ipaファイルはbuild/ios/ipa/xxxx.ipa
にあります。
または、Xcode で Product
→ Archive
を実行し、TestFlight にアップロード。
🔹 Android
実機に Release ビルドをインストール
開発環境(Staging)
flutter run --release --flavor staging --dart-define=PRODUCTION=false
または
flutter build apk --flavor staging --dart-define=PRODUCTION=false
adb install build/app/outputs/flutter-apk/app-staging-release.apk
本番環境(Production)
flutter run --release --flavor production --dart-define=PRODUCTION=true
または
flutter build apk --flavor production --dart-define=PRODUCTION=true
adb install build/app/outputs/flutter-apk/app-production-release.apk
Play Store にアップロードする場合
flutter build appbundle --flavor production --dart-define=PRODUCTION=true --release
📌 作成された aab
ファイルの保存場所
android/app/build/outputs/bundle/productionRelease/app-production-release.aab
📌 Staging 用の aab
ファイル(内部テスト用)
android/app/build/outputs/bundle/stagingRelease/app-staging-release.aab
補足
AndroidでreleaseビルドをしてGoogle Play Storeに公開する場合はアプリを署名するためのkeystoreファイルと呼ばれるものが必要です。
以下、手順です
$ keytool -genkey -v -keystore ./key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
作成されたkeystoreファイルをandroid/appの配下に置きます。
次にandroidディレクトリ配下にkey.propertiesという設定ファイルを作成します。
storePassword=<keystore作成時のパスワード>
keyPassword=<keystore作成時のパスワード>
keyAlias=key
storeFile=key.jks
次にandroid/app/build.gradleを修正します。
// 🔹 `key.properties` の読み込みを追加
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
// buildTypesの前に入れる
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.release
}
}
以上でリリースビルドの設定は完了です。
コマンドまとめ
📌 コマンド一覧
ビルド目的 | ビルドモード | 環境 | Android コマンド | iOS コマンド |
---|---|---|---|---|
開発用デバッグ(Staging) | Debug | Staging | flutter run --flavor staging --dart-define=PRODUCTION=false |
flutter run --dart-define=PRODUCTION=false |
本番環境デバッグ(Production) | Debug | Production | flutter run --flavor production --dart-define=PRODUCTION=true |
flutter run --dart-define=PRODUCTION=true |
社内テスト・内部テスト(Staging) | Release | Staging | flutter build apk --flavor staging --dart-define=PRODUCTION=false --release |
flutter build ios --dart-define=PRODUCTION=false |
本番リリース(Production) | Release | Production | flutter build apk --flavor production --dart-define=PRODUCTION=true --release |
flutter build ios --dart-define=PRODUCTION=true |
Google Play 内部テスト用(Staging) | Release | Staging | flutter build appbundle --flavor staging --dart-define=PRODUCTION=false --release |
N/A |
Google Play 本番公開用(Production) | Release | Production | flutter build appbundle --flavor production --dart-define=PRODUCTION=true --release |
N/A |
App Store / TestFlight アップロード(Staging) | Release | Staging | N/A | flutter build ipa --dart-define=PRODUCTION=false --release |
App Store / TestFlight アップロード(Production) | Release | Production | N/A | flutter build ipa --dart-define=PRODUCTION=true --release |
補足
📌 1️⃣ Debug(デバッグ)と Release(リリース)の違い
これは Flutter のビルドモード であり、アプリの最適化レベルやデバッグ機能の有無 を決めます。
モード | 目的 | 特徴 | 主な用途 |
---|---|---|---|
Debug | 開発・デバッグ用 | - ホットリロードが可能 - assert() が動作- 開発ツール(DevTools)が利用可能 - 最適化されていないので動作が遅い |
- 開発時の動作確認 - デバッグ作業 |
Release | 本番リリース用 | - 最適化されており動作が速い - assert() は無効- デバッグ情報なし(クラッシュログが少なくなる) - アプリサイズが小さくなる |
- 本番環境のビルド - Google Play / App Store にアップロード |
📌 ポイント
-
flutter run
のデフォルトは Debug モード。 -
flutter build apk / ios / appbundle
のデフォルトは Release モード。 -
--release
を付けると Release ビルドになる。
📌 2️⃣ Staging(開発環境)と Production(本番環境)の違い
これは アプリが接続する Firebase や API サーバーの違い です。
環境 | 目的 | 特徴 | 主な用途 |
---|---|---|---|
Staging | 開発・テスト用 | - Firebase / API も開発用の環境を使用 - 開発チームやテスターが使用 - Google Play 内部テストや TestFlight に配布可能 |
- 社内テスト・QAテスト - ストア公開前の最終チェック |
Production | 本番リリース用 | - 一般ユーザーが使用する環境 - Firebase / API も本番用を使用 - 本番リリース版 |
- ユーザーに提供するアプリ - Google Play / App Store への公開 |
📌 ポイント
- Staging は開発チームやテスター向けの環境(本番と同じ設定で動作確認)。
- Production は一般ユーザー向けの環境(本番用 Firebase / API を使用)。
- Staging と Production で Firebase や API のエンドポイントを切り替えることが重要。
📌 3️⃣ Debug / Release × Staging / Production の組み合わせ
Flutter では 「ビルドモード(Debug / Release)」と「環境(Staging / Production)」を組み合わせて使う のが一般的です。
目的 | ビルドモード | 環境 | 用途 |
---|---|---|---|
開発中にデバッグ | Debug | Staging | ホットリロードしながら開発 |
本番リリース前のテスト | Release | Staging | ストアにアップロードする前の動作確認 |
ユーザー向け本番リリース | Release | Production | Google Play / App Store に公開 |
📌 例
-
開発時:
flutter run --flavor staging --dart-define=PRODUCTION=false
-
本番ビルド時:
flutter build appbundle --flavor production --dart-define=PRODUCTION=true --release