新しいアプリを一から Flutter で作ろうと思ってます。で、バックエンドには何かと便利な Firebase を利用する予定です。今の Flutter の開発環境で改めて調べてみると、あれ? Firebase CLI だの Flutterfire CLI だのを使えと出てきます。
昔々、 Flutter で Firebase を使ったときは、単に使いたい Firebase のプロダクトの SDK を pubspec.yaml に書いていたような記憶がありました( 当時は Flutter 1.22.6 を使ってたようです)。
いつのまにやら(推奨の)初期設定の方法が変わっていたようです。ちょっと調べてみたら、下記の記事によると、 Flutter 2.8 の時に、このあたりが結構変わったようです。
FlutterFire CLIを利用してFlutter×Firebaseの環境構築をする #Flutter - Qiita
なので、改めて今どきの流儀で初期設定をしてみたので、メモっておきます。なお、環境は以下の通りです。
- WIndows 11 23H2
- AndroidStudio 2023.1.1 Patch 2
- Flutter 3.22.2
Firebase CLI のインストール
今回使ってみたい Firebase プロダクトは Remote Config です。なので、まずはこちらのスタートガイドを見てみると、 Firebase をセットアップするところから始めるとあるので、これから始めます。リンク先を開いて、 Android のところを見てみます。
このページの説明によると、まずは、 Firebase CLI をインストールする必要があるとのことです。なので、さらにリンクをたどって、下記のページ
Firebase CLI リファレンス | Firebase ドキュメント
の手順に従って、インストールします。
nvm-windows は既にインストール済みなので、まずは、 firebase-tools のインストールを行います。
D:\work\tmp\test>npm install -g firebase-tools added 642 packages in 46s npm notice npm notice New minor version of npm available! 10.2.3 -> 10.9.0 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.0 npm notice Run npm install -g npm@10.9.0 to update! npm notice D:\work\tmp\test>
手順に従って、 Firebase にログインします。
D:\work\tmp\test>firebase login i Firebase optionally collects CLI and Emulator Suite usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you. ? Allow Firebase to collect CLI and Emulator Suite usage and error reporting information? Yes i To change your data collection preference at any time, run `firebase logout` and log in again. Visit this URL on this device to log in: https://accounts.google.com/......... Waiting for authentication... + Success! Logged in as アカウント名 D:\work\tmp\test>
途中でブラウザが立ち上がって、 Firebase CLI を認証するように求められますので、認証しておきます。認証ができると、
D:\work\tmp\test>firebase projects:list ✔ Preparing the list of your Firebase projects ┌──────────────────────┬──────────────────┬────────────────┬──────────────────────┐ │ Project Display Name │ Project ID │ Project Number │ Resource Location ID │ ├──────────────────────┼──────────────────┼────────────────┼──────────────────────┤ │ firebase-sample │ fir-sample-xxxxx │ yyyyyyyyyyyy │ asia-northeast1 │ ├──────────────────────┼──────────────────┼────────────────┼──────────────────────┤ │ temp │ temp-xxxxx │ yyyyyyyyyyyy │ [Not specified] │ ├──────────────────────┼──────────────────┼────────────────┼──────────────────────┤ n project(s) total. D:\work\tmp\test>
こんな感じに、プロジェクトの一覧も見ることができます。
firebase プロジェクトの初期化
なお、上記の手順では、 firebase プロジェクトの初期化も行うようになってます。試しに実行してみると、
D:\work\tmp\test>firebase init ######## #### ######## ######## ######## ### ###### ######## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ###### ######## ######### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ######## ## ## ###### ######## You're about to initialize a Firebase project in this directory: D:\work\tmp\test ? Are you ready to proceed? Yes ? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed) >( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore ( ) Genkit: Setup a new Genkit project with Firebase ( ) Functions: Configure a Cloud Functions directory and its files ( ) Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys ( ) Storage: Configure a security rules file for Cloud Storage ( ) Emulators: Set up local emulators for Firebase products (Move up and down to reveal more choices)
のように どの Firebase プロダクトを使うか求められます。
とりあえず、今のところ上記に含まれているものはなかったので、何も選択せずに enter を押しておきます( ERROR となり終了します)。この部分は、必要がでてきてから再度やればよさそうですね。
Flutterfire CLI のインストール
Firebase CLI のインストールが終わったので、次は手順によると Flutterfire CLI をセットアップします。
firebase login は実施済みなので、
D:\work\tmp\test>dart pub global activate flutterfire_cli Downloading packages... (2.5s)s) + ansi_styles 0.3.2+1 (中略) Building package executables... (2.5s) Built flutterfire_cli:flutterfire. Installed executable flutterfire. Warning: Pub installs executables into C:\Users\mor\AppData\Local\Pub\Cache\bin, which is not on your path. You can fix that by adding that directory to your system's "Path" environment variable. A web search for "configure windows path" will show you how. Activated flutterfire_cli 1.0.0. D:\work\tmp\test>
とインストールしておきます。また、パスが通ってないと警告が出ているので、パスを通しておきます。
初期化
flutterfire コマンドを使って、初期化を行います。この初期化の際に、 Firebase 側のプロジェクトの設定も行われ、選択したプラットフォームに対するアプリの登録なんかも実施されます。
Firebase 側のプロジェクトにアプリを登録したことがあるかたはわかると思いますが、アプリ登録する際に、パッケージ名や bundleId を指定して登録します。なので、これを実行する前に Flutter のプロジェクトのパッケージ名とか bundleId とかが正しいか確認しておき、必要があれば修正しておくといいと思います(ハイフンやアンダースコアの扱いに関して、思ったものと違っている可能性あります)。
パッケージ名・ bundleId に問題がないことを確認したら、初期化を実行します。今回は iOS の bundleId にハイフンが入っているため、実行時のオプション(--ios-bundle-id)で明示的に指定しています(これを明示的に指定しないとハイフンのない bundleId でアプリが登録されてしまいました)。
D:\work\tmp\test>flutterfire configure --ios-bundle-id=com.mori-soft.apps.flutter-test i Found 4 Firebase projects. ? Select a Firebase project to configure your Flutter application with › ❯ fir-sample-e1d7c (firebase-sample) xxxxxx (xxxxxx) yyyyyy (yyyyyy) flutter-test (flutter-test) <create a new project>
最初は、 Firebase プロジェクトの選択を求められます。既存のプロジェクトを選ぶことも、新規に作成することも可能です。今回は既存のプロジェクトを選択しました。
次にプロジェクトがサポートするプラットフォームを選択します。
? Which platforms should your configuration support (use arrow keys & space to select)? › ✔ android ✔ ios macos web windows
その次は、 Android のパッケージ名の入力をします。
? Which Android application id (or package name) do you want to use for this configuration, e.g. 'com.example.app'? › com.mori_soft.apps.flutter_test
すると、以下のような感じで、 Firebase プロジェクト側に、 Android と iOS のアプリが登録されます。
i Firebase android app com.mori_soft.apps.flutter_test registered. i Firebase ios app com.mori-soft.apps.flutter-test is not registered on Firebase project flutter-test. i Registered a new Firebase ios app on Firebase project flutter-test. Firebase configuration file lib\firebase_options.dart generated successfully with the following Firebase apps: Platform Firebase App Id android n:xxxxxxxxxxx:android:yyyyyyyyyyyyyyyyy ios n:xxxxxxxxxxx:ios:zzzzzzzzzzzzzzzz Learn more about using this file and next steps from the documentation: > https://firebase.google.com/docs/flutter/setup D:\work\tmp\test>
上記のログは何度かテストしていたので、 Firebase プロジェクトに登録済みの Android アプリがあった場合のものになります。このあたりは、アプリの登録状況に応じて表示されるメッセージが若干異なることになると思います。
ここまでできたら、実際に Firebase コンソールを開いて、該当するプロジェクトを確認してみます。すると、
のように追加されていました。
あと、 flutterfire configure を実行すると firebase.json ファイルも作成されていました(firebase init を実行すると作成されると上記手順で触れられていたやつです)。
firebase_core を追加
手順通りに追加します。
D:\work\tmp\test>flutter pub add firebase_core
一応、 firebase configure も再実行したのですが、結果に変わりはなかったです。
コードの修正
次に、 lib/main.dart を修正します( Flutter のプロジェクトを作成した際のサンプルを元にしています)。 import の修正は問題ないかと思います。
問題は、 Firebase.initializeApp をどう呼び出すかになります。
手順には、 Firebase.initializeApp を呼びだして、引数にオプションを渡せ、とだけあるんだけど、具体的なコードが載ってません。非同期関数ですのでちょっと厄介です。
ま、結論としては、以前書いたコードや、こちらの記事を参考にして、 FutureBuilder を使うのがスマートそうなので、それで対応します。
lib/main.dart の MyApp を下記のように修正します。
class MyApp extends StatelessWidget { const MyApp({super.key}); // This widget is the root of your application. @override Widget build(BuildContext context) { return FutureBuilder( future: Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ), builder: (context, snapshot) { if (snapshot.hasError) { return Text("エラー"); } if (snapshot.connectionState == ConnectionState.done) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } return CircularProgressIndicator(); }, ); } }
FutureBuilder で Firebase の初期化が終わってから、 MyHomePage を返すような感じですね。
ビルド
ここまでで Firebase を使う準備ができたので、一度ビルドしてみます。あれ?なんかエラーが出ます。
FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:checkDebugDuplicateClasses'. > A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable > Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.22 (org.jetbrains.kotlin:kotlin-stdlib:1.8.22) and jetified-kotlin-stdlib-jdk8-1.7.10 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10) Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations found in modules jetified-kotlin-stdlib-1.8.22 (org.jetbrains.kotlin:kotlin-stdlib:1.8.22) and jetified-kotlin-stdlib-jdk7-1.7.10 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10) Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations$ReflectSdkVersion found in modules jetified-kotlin-stdlib-1.8.22 (org.jetbrains.kotlin:kotlin-stdlib:1.8.22) and jetified-kotlin-stdlib-jdk7-1.7.10 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10)
下記を参考にすると、どうも依存関係の問題が生じているようです。
- 【Flutter】「Execution failed for task ':app:checkDebugDuplicateClasses'.」発生時の対処法|辛島信芳
- 【Flutter 解決済】Execution failed for task ‘:app:checkDebugDuplicateClasses’. のエラー│Flutter Salon
解決策もここに載っていて、 app/build.gradle を開いて、以下を追加すれば、OKのようです。
dependencies { constraints { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") { because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") } implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") { because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") } } }
で、エミュレータで動かしてみると、おぉ、問題なく動きますね。
ということで、やっと Firebase を使う準備ができました。
まとめ
Firebase CLI / Flutterfire CLI を使うのは初めてだったので若干手間取りましたが、 Android / iOS / Firebase プロジェクト といった関連するすべての設定をまとめてやってくれるのは確かに便利ですね。
あとは使いたい Ffirebase のプロダクトを個別に追加していけば使えるはずです。ということで、早速 Remote Config を試してみようと思います。