はじめに
最近FlutterとFirebaseを使ってWebアプリを作る機会があったので,その中で困った部分を記載します.Flutterも,Firebaseも業務で触るのは初めてで,色々手探りの中アプリを作成中です.
お題
Flutterで作ったコードをFirebase Hostingする際,dev環境と本番環境それぞれにデプロイしたいと考えています.firebase deploy --project=<プロジェクト>
だけでは,Hosting先が変わるのみで,Remote Configなどのサービスは,コード内で指定したFirebaseのプロジェクトを参照してしまいました.
そこで,コードを修正することなくデプロイ先の環境を切り替え,その環境のサービスを利用する対応を行ないます.今回はRemote Configを使って,それぞれの環境に変数を登録しておき,環境に応じてその値を用いるシーンを考えます.
結論
今回envファイルを用いて,Firebaseの初期化とビルドを切り替えるようにしています.Firebaseの初期化も環境によって切り替えることで,それぞれのRemote Configに登録している変数を参照することができるようになります.
(flutter create myapp
やfirebase init
を実行済みで,ここでの記載は省略します.)
ビルド時にenvファイルを切り替える
ビルドコマンド時に,定義ファイルを指定するようにします.dev.env
,prod.env
それぞれにAPI keyなど,Firebaseの初期化に必要な値を入れます.
flutter build web --dart-define-from-file=dart_files/prod.env
apiKey=xxxxxx
authDomain=xxxxxx
projectId=xxxxx
storageBucket=xxxxx
messagingSenderId=xxxxx
appId=xxxxxxx
Firebaseの初期化
envファイルに記載した値を用いて初期化します.
void main() async {
const apiKey = String.fromEnvironment('apiKey');
const authDomain = String.fromEnvironment('authDomain');
const projectId = String.fromEnvironment('projectId');
const storageBucket = String.fromEnvironment('storageBucket');
const messagingSenderId = String.fromEnvironment('messagingSenderId');
const appId = String.fromEnvironment('appId');
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: apiKey,
authDomain: authDomain,
projectId: projectId,
storageBucket: storageBucket,
messagingSenderId: messagingSenderId,
appId: appId
),
);
runApp(const MyApp());
}
デプロイするプロジェクトを指定
.firebaserc
を手動で修正し,projects
に,prod環境とdev環境を定義します.
そして,デプロイ時にプロジェクトを指定して,デプロイするプロジェクトを切り替えます.
{
"projects": {
"default": "myapp-prod",
"dev": "myapp-dev"
}
}
firebase deploy --project=dev
結果
Remote Configから読み取った変数env
をそのまま表示するWebアプリです.それぞれ登録しておいたenv
の値を表示してくれています.
production環境でのHosting
development環境でのHosting
まとめ
今回はFirebaseのHosting環境に応じて,そこで使うためのサービス含めて切り替えることを検討しました.上記のように実現しましたが,正直ベストプラクティスなのかわかっていません.一案としてご参考になれば幸いです.作成したコードはこちらに公開しております.
余談
ローカルでの確認では,Remote Configから値を読み取ることができるのに,Hostingすると値を読み取ることができない状況に陥ることがありました.結論としては,
flutter clean
をしてから,ビルドとデプロイをすれば解決しました.たったこれだけのことに苦労しました.