開発環境と本番環境を使い分ける

2023年6月3日

開発環境
OS:Windows 11
SDK:VS Code + flutter 3.7.5

概要

データベースを使ったアプリ開発で必要になってくるのが開発環境と本番環境の分離。

開発用データベースと本番用データベースをコマンドベースで使い分けます。

Firebase設定ファイル

Firebaseのアクセス制御は、CLIでFirebase設定を行った際に自動生成するオプションファイル、firebase_options.dartの定義に従い行われます。

import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
    show defaultTargetPlatform, kIsWeb, TargetPlatform;

class DefaultFirebaseOptions {
  static FirebaseOptions get currentPlatform {
    if (kIsWeb) {
      return web;
    }
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        return android;
      case TargetPlatform.iOS:
        return ios;
      case TargetPlatform.macOS:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for windows - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      case TargetPlatform.windows:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for windows - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      case TargetPlatform.linux:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for linux - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      default:
        throw UnsupportedError(
          'DefaultFirebaseOptions are not supported for this platform.',
        );
    }
  }

  static const FirebaseOptions web = FirebaseOptions(
    apiKey: '***************',
    appId: '***************',
    messagingSenderId: '***************',
    projectId: '***************',
    authDomain: '***************',
    databaseURL: '***************',
    storageBucket: '***************',
    measurementId: '***************',
  );

  static const FirebaseOptions android = FirebaseOptions(
    ~
  );

  static const FirebaseOptions ios = FirebaseOptions(
    ~
  );
}

ファイルの中身は、android、iOS、Web、デスクトップアプリ用にそれぞれ下記の設定値が

定義されています。

apiKey
appId
messagingSenderId
projectId
authDomain
databaseURL
storageBucket
measurementId

これらの設定値は、特定のFirebaseプロジェクトを指し示すものであり、

開発用、本番用と2つのプロジェクトを用意した場合は

2つのオプションファイルを使い分ける必要があります。

定義

ステップ1)ファイル名を分け、オプションファイルを共存させる

2つのオプションファイルを使い分けるためにファイル名を変更し、同一フォルダ内で管理します。

そこでlibフォルダの直下にgenフォルダを作成し、オプションファイルを格納することにします。

開発用)lib/gen/firebase_option_dev.dart

本番用)lib/gen/firebase_option_prod.dart

ステップ2)ソースコードでFlavorを使い、参照ファイルを使い分ける

FirebaseのInitial処理で参照先のオプションを振り分けます。

Flavorは、実行時に入力するコマンドオプションであり、

実行時に入力した値に従い、プログラムが実行します。

import 'package:firebase_core/firebase_core.dart';
import 'package:sample/gen/firebase_options_dev.dart' as dev;
import 'package:sample/gen/firebase_options_prod.dart' as prod;

void main() async {
  await Firebase.initializeApp(
    options: options: getFirebaseOptions(),
  );  
  runApp(MyApp());
}

FirebaseOptions getFirebaseOptions() {
  const flavor = String.fromEnvironment('FLAVOR');
  switch (flavor) {
    case 'dev':
      return dev.DefaultFirebaseOptions.currentPlatform;
    case 'prod':
      return prod.DefaultFirebaseOptions.currentPlatform;
    default:
      throw ArgumentError('No flavor');
  }
}

上記ではクラス「DefaultFirebaseOptions」が開発と本番で共存するため、

オプションンファイルをimportする際に「as」定義行い、使い分けています。

これでFlavorの入力値により参照先のFirebaseプロジェクトを切り替えることができます。

これで定義は終了です。

Flavorを使い、実行する

あとは実行する際にコマンドラインでFlavorを指定します。

デバッグ時) 開発環境のFirebaseを使用する

flutter run -d (デバイスID) –dart-define=FLAVOR=dev

アプリ作成時) 本番環境のFirebaseを使用する

flutter build appbundle –dart-define=FLAVOR=prod

パッケージIDを開発と本番で分ける場合は更にAndroid Studio、及び、Xcodeの変更が必要となります。

今回は以上です。