概要
前回は、手動で 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 で不可
対応状況は以下で確認できる。
チュートリアル
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 にアップ済み。
エラー
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;
}
}
}
コメント