6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Flutter】Firebase(Firestore) 疎通までのチュートリアル

Posted at

概要

Flutter でFirebase を利用してみようと、webの情報を参考に進めていましたが、古い情報も多いらしく上手くいかないことがありました。
結局、公式ドキュメントを参考に進めましたが、それでも躓いた点があったため、メモとして残しておきます。

Flutter 学習中の初心者の記事のため、誤った情報が含まれているかもしれません。
間違っている情報や、改善点あればコメントにて教えていただけると嬉しいです。

なお、記事中の情報は、2021/07/04 現在のものです。

ターゲット

  • Flutter + Firebase の組合せ、チュートリアル通りに進めているのに、何故かうまくいかない人

この記事の説明範囲

  • Firebase プロジェクトの作成からFirebase(Firestore)への疎通確認まで
    • アプリで入力したデータをFirestore で保存するアプリ作成
    • 保存するだけで読み出し部分は作らない

準備

0. [AndroidStudio] テスト用プロジェクトを作成

Flutter プロジェクトを作成
名前は何でもいいですが、今回は"firebase-test"とします。

1.[Firebase] プロジェクトを作成する

Firebase console より、プロジェクトを作成します。
こちらも名前は何でもいいですが、ここでは先ほどの名前と揃えておきます。

その後の選択はデフォルトのまま進めてOKです

2.アプリの登録

作成したプロジェクト画面より、android を選択

2.1 アプリ情報を入力

  • Android パッケージ名
    • android\app\build.gradle のapplicationId に記載されているもの
    • 他は空欄のままで「アプリを登録」

3.google-services.json をダウンロード

画面に従いgoogle-services.json をダウンロード。
ダウンロードしたgoogle-services.json を Flutterプロジェクトの(project)\android\app直下に配置。
2021-07-04_11h15_22.png

4.build.gradle の修正

android\build.gradleandroid\app\build.gradle 2つのgradle に下記の通り追記する
(同名ファイルが2つあるので注意)

android\build.gradle

android\build.gradle
buildscript {
  repositories {
    // 下記行があることを確認(なければ追加しておく)
    google()  // Google's Maven repository
  }
  dependencies {
    ...
    // 下記行を追加
    classpath 'com.google.gms:google-services:4.3.8'
  }
}
allprojects {
  ...
  repositories {
    // 下記行があることを確認(なければ追加しておく)
    google()  // Google's Maven repository
    ...
  }
}

android\app\build.gradle

android\app\build.gradle
// "android" セグメントの上に行を追加
apply plugin: 'com.google.gms.google-services'  // Google Services plugin

android {
  // ...
}

5.CloudFirestoreプラグインのインストール

(公式)Firestoreドキュメント
1. pubspec.yaml を編集

android\pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  firebase_core: "^1.3.0" # 追加
  cloud_firestore: "^2.2.2" # 追加

2. AndroidStudioのターミナルより flutter pub get 実行
3. flutter run を実行し、正常に起動することを確認しておく
※嵌りポイント
ここで下記のエラーが発生することがあります

D8: Cannot fit requested classes in a single dex file (# methods: 79185 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
...
(以下略)

発生した場合は、エラーメッセージの解決方法 に従い、下記の通りandroid\app\build.gradle を編集後、再度flutter run してみてください。

android\app\build.gradle
android {
    defaultConfig {
        ...
        minSdkVersion 15
        targetSdkVersion 28
        multiDexEnabled true // 追加
    }
    ...
}
dependencies {
    implementation "androidx.multidex:multidex:2.0.1" // 追加
}

6.CloudFirestore データベースの作成

1. Firebase のコンソールから"Firestore Database"の「データベースの作成」を選択

2.「テストモードで開始する」にチェックを入れ次へ

3.あとはデフォルトのままでOK

これで準備は完了です。
この後は実際にFlutterプロジェクトからFirestore を利用してみます。

Firebase を利用してみる

(公式)Firestoreチュートリアル を参考に、簡単なサンプルプログラムを作成しました。
ソースコードは後述するので、必要に応じてコピペしてください。
氏名、年齢を入力し、「ユーザ登録」ボタンを押下するとFirestore にデータが保存されます。

登録ボタン押すと、Firestore上にデータが保存される。

ソースコード

main.dart

長いので折り畳み
main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_test/add_user.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized(); // 追加
  await Firebase.initializeApp(); // 追加
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _name = "";
  int _age = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter + Firebase デモ"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              decoration: InputDecoration(
                labelText: "氏名",
                hintText: "田中 太郎",
              ),
              onChanged: (inputText) {
                setState(() {
                  _name = inputText;
                });
              },
            ),
            TextField(
              keyboardType: TextInputType.number,
              inputFormatters: [FilteringTextInputFormatter.digitsOnly],
              decoration: InputDecoration(
                labelText: "年齢",
                hintText: "28",
              ),
              onChanged: (inputText) {
                print(inputText);
                setState(() {
                  _age = int.parse(inputText);
                });
              },
            ),
            AddUser(_name, _age),
          ],
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

add_user.dart(新規作成)

libフォルダ配下にadd_user.dartを新規作成で追加

長いので折り畳み
add_user.dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class AddUser extends StatelessWidget {
  final String name;
  final int age;

  AddUser(this.name, this.age);

  @override
  Widget build(BuildContext context) {
    CollectionReference users = FirebaseFirestore.instance.collection('users');
    Future<void> addUser() {
      print(this.age);
      return users
          .add({
        'full_name': name, // 田中太郎
        'age': age // 42
      })
          .then((value) => print("User Added"))
          .catchError((error) => print("Failed to add user: $error"));
    }
    return ElevatedButton(
      onPressed: addUser,
      child: Text(
        "ユーザ登録",
      ),
    );
  }
}
## 実装上の注意点 ※嵌りポイント Firebase の使用には、main関数内で下記の記述が必要?っぽい。 少なくともFirestore のドキュメントには記載なさそうだったけどどこかに記載あるのかな。
main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized(); // 追加
  await Firebase.initializeApp(); // 追加
  runApp(MyApp());
}

参考リンク

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?