FlutterFire CLI で Firebase と連携し Firestore へデータ追加

概要

前回は、手動で Flutter と Firebase を連携し、Firestore へデータを書き込むチュートリアルを行った。

今回は FlutterFire CLI を利用して Firebase 連携を行う。

環境

  • Flutter 2.10.2
  • flutterfire_cli 0.1.1+2
  • firebase_core 1.12.0
  • cloud_firestore: ^3.1.8
  • iPhone SE2 (2nd generation)シミュレータ

設計

FlutterFire CLI

公式ドキュメントでは Flutter Firebase 連携に FlutterFire CLI を推している。

メリットは google-services.json (Android用) や GoogleService-Info.plist (iOS用) を手動で追加しなくていい。

デメリットは、出て日が浅いため、2022年2月時点で以下が対応中。

  • Analytics : Android で動作が異なる可能性
  • Crashlytics : iOS, Android, Mac で動作が異なる可能性
  • Performance Monitoring : Android で不可

対応状況は以下で確認できる。

CLI | FlutterFire
The FlutterFire CLI is a useful tool which provides commands to help ease the installation process

チュートリアル

Firebase CLI 準備

以下を参照。

FlutterFire CLI 準備

今回は FlutterFire CLI を使い、Firebase 環境を構築する。

dart にインストールする。

dart pub global activate flutterfire_cli

2022年2月23日時点でバージョン 0.1.1+2 が入った。

$ flutterfire -v
0.1.1+2

flutterfire configure コマンドで Firebase プロジェクトの選択や新規作成が可能となる。

$ flutterfire configure

i Found 5 Firebase projects.
? Select a Firebase project to configure your Flutter application with ›
  eigodealarm (EigoDeAlarm)
  english-8d1b7 (YoutubeEnglish)
  first-project-179412 (first-project)
  flutter-oneweek-todo (flutter-oneweek-todo)
  flutter-test-1a754 (flutter-test)
❯ <create a new project>

Flutter プロジェクト作成

Org(組織) を指定し Flutter プロジェクト作成。

flutter create firestore_cli --org com.runble1.firestoreCli
cd firestore_cli

Firebase, Firestore 用のライブラリ追加。

flutter pub add firebase_core
flutter pub add cloud_firestore

iOS 利用バージョンを上げておく。

vi Podfile
# platform :ios, '9.0'
platform :ios, '10.12'

この時点で一度アプリが起動することを確認しておく。
iOS のバージョンを上げたため、最初の起動が死ぬほど遅い。

flutter run

FlutterFire CLI で Firebase プロジェクト作成

Flutter プロジェクトディレクトリ内で flutterfire コマンド実行。

flutterfire configure

create new project を選択し、新規 Firebase プロジェクトを作成。

  • Platform : ios
% flutterfire configure
i Found 5 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) · firestore-cli
i New Firebase project firestore-cli created succesfully.
✔ Which platforms should your configuration support (use arrow keys & space to select)? · ios
i Firebase ios app com.runble1.firestoreCli.firestoreCli is not registered on Firebase project firestore-cli.
i Registered a new Firebase ios app on Firebase project firestore-cli.

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

Platform  Firebase App Id
ios       1:895935164213:ios:52c2a1f56833ebefb4667c

Learn more about using this file in the FlutterFire documentation:
 > https://firebase.flutter.dev/docs/cli

コンソールからも確認できる。

lib/firebase_options.dart が追加される。
これには Firebase 認証情報が詰まっている(ダミーで上書きして載せてる)。

// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
    show defaultTargetPlatform, kIsWeb, TargetPlatform;

/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
///   options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
  static FirebaseOptions get currentPlatform {
    if (kIsWeb) {
      throw UnsupportedError(
        'DefaultFirebaseOptions have not been configured for web - '
        'you can reconfigure this by running the FlutterFire CLI again.',
      );
    }
    // ignore: missing_enum_constant_in_switch
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for android - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
      case TargetPlatform.iOS:
        return ios;
      case TargetPlatform.macOS:
        throw UnsupportedError(
          'DefaultFirebaseOptions have not been configured for macos - '
          'you can reconfigure this by running the FlutterFire CLI again.',
        );
    }

    throw UnsupportedError(
      'DefaultFirebaseOptions are not supported for this platform.',
    );
  }

  static const FirebaseOptions ios = FirebaseOptions(
    apiKey: 'aaaa',
    appId: 'bbbb',
    messagingSenderId: '1111',
    projectId: 'firestore-cli',
    storageBucket: 'firestore-cli.appspot.com',
    iosClientId: '895935164213-cccc.apps.googleusercontent.com',
    iosBundleId: 'com.runble1.firestoreCli.firestoreCli',
  );
}

Firestore データベース作成

上で作った Firebase プロジェクトに Firestore データベースを作成する。

これはコンソールから作成するしかない。いつか CLI からやりたい。

  • 左サイドメニュー → Firestore Database → データベースの作成

以下の設定で作成する。

  • テストモード(本番モードは今度!)
  • asia-northeast1

users コレクションを作成。
比較用の初期ドキュメントも手動で追加しておく。

サンプルアプリ

カウンターアプリと公式ドキュメントを悪魔合体させた。汚いのは許して。

vi main.dart

Firebase の初期化時に firebase_options.dart の情報を使っている。

import 'package:flutter/material.dart';

import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

import 'firebase_options.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firestore Add Sample',
      home: FirestoreSave(),
    );
  }
}

class FirestoreSave extends StatefulWidget {
  @override
  _MyFirestorePageState createState() => _MyFirestorePageState();
}

class _MyFirestorePageState extends State<FirestoreSave> {
  @override
  Widget build(BuildContext context) {

    CollectionReference users = FirebaseFirestore.instance.collection('users');

    Future<void> addFirestoreUser() {
      // Call the user's CollectionReference to add a new user
      return users
          .add({
            'full_name': "fullName",
            'company': "company",
            'age': "age" 
          })
          .then((value) => print("User Added"))
          .catchError((error) => print("Failed to add user: $error"));
    }

    return Scaffold(
      appBar: AppBar(
        title: Text("title"),
      ),
       body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              'Body'
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: addFirestoreUser,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

起動・確認

アプリを起動する。

flutter run

いつもの画面が立ち上がるので、右下の FAB をクリック。

ローカルには「User Added」と刻まれる。

Firestore のコンソールからデータ追加を確認。

まとめ

firebase_options.dart は認証情報が入っているため git 管理しちゃダメ。 .gitignore に例外として追加しておくこと。

コードのまとめて github にアップ済み。

GitHub - runble1/firestore_add
Contribute to runble1/firestore_add development by creating an account on GitHub.

エラー

flutter: Failed to add user: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.

データ追加時に「flutter: Failed to add user: [cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.」のエラー発生。

Firestore のパーミッションエラー。

Firestore ルールは、本番モードで作成したデフォルトのもの。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

「すべてを許可」の場合は問題なく追加できた。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

認証必須の場合。追加できなかった・・・

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
       allow read, write: if request.auth != null;
    }
  }
}

参考

FlutterからCloud Firestoreのデータ取得 & データ書き込み - Qiita
はじめに Flutterを使って試しに何かネイティブアプリを作ろうと考えていた時、バックエンドの構成で迷ったため、最近流行っているCloud Firestore を使ってみることにした。 そもそもFirebase自体の利用が初め...

コメント

タイトルとURLをコピーしました