📝

Flutter Firebase CLI での Firestore データベース設定の覚書

2025/03/01に公開

この記事について

趣味でプログラミングを勉強している状態なので、この作業はそう頻繁にやることはなくて、毎回忘れて最初から迷うことになるので、覚書を作っておく。
一応、勉強がてら動作することの確認までやっていますが、作業手順の記録が主目的なので、コードは非常にいい加減です。

作業時期

2025年2月28日、3月1日

前提環境など

この記事に含まないこと、または、前提環境

この記事は、以下の設定は完了している状態での Firestore データベースの設定手順なので、以下の内容は含まない。

  • (Firebase CLI に必要な) node.js の導入 (インストール済み)
  • Firebase CLI の導入 (インストール済み)
  • Firebase へのログイン (アカウントあり、ログイン済み)
  • Flutter Fire CLI のインストール (% dart pub global activate flutterfire_cli の実行)

上記それぞれの確認は以下の方法で可能。

% node -v
v23.7.0

% npm ls -g | grep firebase     
├── firebase-tools@13.32.0

% firebase login
Already logged in as (メール@アドレス)

% dart pub global list
flutterfire_cli 1.1.0

Flutter Fire をインストールする自作サンプルアプリ

Firestore データベースを Flutter プロジェクトに対して設定するので、サンプルとして以下のような、ボタンを押すと

  • String _date
  • String _time

の2つのプロパティに、その時点での日付と時刻を文字列で保存するアプリを使います。
状態管理に Stateful Widget を使用した単純なアプリで、データの永続化はされていませんので、起動時には常にデフォルトの文字列を表示します。

一応、コードも書いておきます。

サンプル
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'State Management Sample',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // State となる変数
  String _date = '2025/1/1';
  String _time = '12:34:56';

  // State を更新する処理
  void _update() {
    final now = DateTime.now().toUtc().add(const Duration(hours: 9));
    final dateFormatter = DateFormat('yyyy/M/d');
    final nowDateStr = dateFormatter.format(now);
    final timeFormatter = DateFormat('H:m:s');
    final nowTimeStr = timeFormatter.format(now);

    setState(() {
      _date = nowDateStr;
      _time = nowTimeStr;
    });
  }

  // State を表示する UI
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('State Management Sample'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('ボタンを押すと、現在の日付と時間が分かります'),
            const SizedBox(height: 10),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text('ただいま '),
                const SizedBox(width: 10),
                Column(
                  children: [
                    Text(
                      _date,
                      style: Theme.of(context).textTheme.headlineMedium,
                    ),
                    Text(
                      _time,
                      style: Theme.of(context).textTheme.headlineMedium,
                    ),
                  ],
                ),
                const SizedBox(width: 10),
                const Text('です。 '),
              ],
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                _update();
              },
              child: const Text('いま何時?'),
            ),
          ],
        ),
      ),
    );
  }
}

作業手順

Flutte プロジェクト に Firestore CLI を使って Firestore データベースを構成する手順。

flutterfire configure の実行

Flutter プロジェクト内で % flutterfire configure を実行すると

  • 既存の Firebase プロジェクトを探してくるので、今回は <create a new project> を選択
  • プロジェクト名を設定
  • プラットフォームの選択

の順で進む

% flutterfire configure  
i Found 2 Firebase projects.
✔ Select a Firebase project to configure your Flutter application with · <create a new project>
✔ Enter a project id for your new Firebase project (e.g. my-cool-project) · (プロジェクト名を入力)
i New Firebase project flutter-fire-cli-setup created successfully.
? Which platforms should your configuration support (use arrow keys & space to select)? 
✔ android
✔ ios
  macos
✔ web 
  windows

完了すると以下のようにプラットフォームごとの bundle ID が作成される。(一部伏せ字化)

Firebase configuration file lib/firebase_options.dart generated successfully with the following Firebase apps:

Platform  Firebase App Id
web      1:15xxxxxxxx40:web:bb0xxxxxxxxxxxxxxxxx1cd
android  1:15xxxxxxxx40:android:920xxxxxxxxxxxxxxxx1cd
ios      1:15xxxxxxxx40:ios:3a3xxxxxxxxxxxxxxxxxxx1cd

Learn more about using this file and next steps from the documentation:
 > https://firebase.google.com/docs/flutter/setup

git で見てみると以下のファイルが変更されています。

Firestore データベースの作成

Firebae のサイト にログインして Firebase コンソールに行くと、作成したプロジェクトが表示されている。

プロジェクトを選択して[Firestore Database]を選択

[データベースを作成]を選択

ロケーションの選択。ここでは "asia-northeast1(Tokyo)"を選択。

モードの選択。今回は"テストモード"を選択。

しばらく待つ

データベースの構成画面が表示される

Firebase コンソールの画面上でデータベースを構成する

データベース構成画面で、[コレクションを開始]してコレクションIDをつける

ドキュメントIDをつけて、フィールドを設定する

データベースの構成完了

Flutter プロジェクト(pubspec.yaml)でのパッケージの追加

以下のパッケージを追加

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  intl:
  firebase_core: #これを追加
  cloud_firestore: #これを追加

Firebase をコードに追加する

import を追加し、main() の先頭に Firebase の初期化のコードを記入。

main.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:firebase_core/firebase_core.dart'; //追加
import 'package:flutter_fire_cli_setup/firebase_options.dart'; //追加

void main() async {
  // 追加 ここから
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  // ここまで
  runApp(const MyApp());
}

SDK の Minimum バージョンの変更

この段階で一度エミュレーターを実行する。
Android SDK や iOS SDK のバージョンの関係でエラーになる場合は修正する。
以下は iOS の場合の修正方法。

Xcode で iOS の Minimum バージョンを変更する

Xcodeのプロジェクトナビゲータで、「Runner」ターゲットを選択

「General」タブを選択
「Minimum Deployments」をあげる。(今回は選択できる状態になっていた中で一番低いバージョン 15.6 を選択)

Podfile の修正

プロジェクトのiosディレクトリにあるPodfileファイルを開いて以下の行を修正

platform :ios, '15.6'

pod install の実行

ios ディレクトリに移動して実行すること

% cd ios
% pod install

Flutter プロジェクトのクリーンビルド

以下のコマンド。結構時間がかかる

flutter clean
flutter pub get
flutter run

以上でエミュレーターが動作することを確認してから次に進む。

Firestore データベースの利用

以上で Firestore データベースが利用できるようになっている。
サンプルのアプリのコードを firestore を利用するように修正。

サンプル
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_fire_cli_setup/firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'State Management Sample',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({super.key});

  final _collection = FirebaseFirestore.instance.collection(
    'date-time-checker',
  );

  void _update() {
    final now = DateTime.now().toUtc().add(const Duration(hours: 9));
    final dateFormatter = DateFormat('yyyy/M/d');
    final nowDateStr = dateFormatter.format(now);
    final timeFormatter = DateFormat('H:m:s');
    final nowTimeStr = timeFormatter.format(now);

    _collection.doc('checked-time').update({
      'date': nowDateStr,
      'time': nowTimeStr,
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('State Management Sample'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('ボタンを押すと、現在の日付と時間が分かります'),
            const SizedBox(height: 10),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text('ただいま '),
                const SizedBox(width: 10),
                StreamBuilder(
                  stream: _collection.snapshots(),
                  builder: (context, snapshot) {
                    if (snapshot.hasError) {
                      return const Text('エラーが発生しました');
                    } else if (!snapshot.hasData) {
                      return const CircularProgressIndicator();
                    }
                    String date = snapshot.data!.docs[0]['date'];
                    String time = snapshot.data!.docs[0]['time'];
                    return Column(
                      children: [
                        Text(
                          date,
                          style: Theme.of(context).textTheme.headlineMedium,
                        ),
                        Text(
                          time,
                          style: Theme.of(context).textTheme.headlineMedium,
                        ),
                      ],
                    );
                  },
                ),
                const SizedBox(width: 10),
                const Text('です。 '),
              ],
            ),
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                _update();
              },
              child: const Text('いま何時?'),
            ),
          ],
        ),
      ),
    );
  }
}

Firestore のデータが更新されて、そのデータが表示されるようになった。

参考にした記事など

Udemy オンラインコース 【Flutter】 Firestore 実践ガイド
Firebase CLI リファレンス
FlutterFire CLIを利用してFlutter×Firebaseの環境構築をする
(あと、ChatGPT、Gemini に質問したり、エラーを丸投げしたり・・・)

Discussion