FlutterでFirestoreと連携してみた

以前、[「Flutter環境を作ってみた」](https://qiita.com/teracy55/items/844f79dfdfd4b011780b)でFlutter環境を構築した。
今回は、Firestoreと連携してみようと思う。
（とりあえずAndroid向け）

# 作るもの
Firestoreのあるコレクション内のドキュメントをリスト表示するだけの簡単なもの。


# FlutterでFirebaseを使うための準備
[こちらのドキュメント](https://firebase.google.com/docs/flutter/setup?hl=ja)に従って進めていく

## Firebaseプロジェクトの作成とアプリの登録
### アプリの追加
・対象のFirebaseプロジェクトにて、Androidアプリの追加を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/61bc03eb-60c8-a812-943d-040c85dfa8ff.png)


・パッケージ名、アプリ名を入力
　※今回、証明書は登録しない
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/3814c9ac-523a-d9f1-ecea-9a1e4786e121.png)
⇒パッケージ名はFlutterプロジェクトの以下の値を指定

```android/app/build.gradle
android {
    ・・・
    defaultConfig {
        applicationId "{パッケージ名}"
        ・・・
```

・設定ファイル（google-services.json）をダウンロード
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/ec648b72-7c65-6297-df79-2c95ff497f86.png)

### 設定ファイルをFlutterプロジェクトに配置
・上記でダウンロードしたファイルを、Flutterプロジェクトのandroid/app下に置く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/5576ca42-7409-22fc-1521-cfb90fbd14c3.png)


## Flutterプロジェクトの設定

### google-servicesプラグインの追加
Android アプリで Firebase サービスを利用するにはgoogle-servicesプラグインが必要らしいので、追加

```android/build.gradle
buildscript {
    dependencies {
        ・・・
        classpath 'com.google.gms:google-services:3.2.1'  // Google Services plugin
    }
}
allprojects {
    repositories {
        ・・・
        google()
    }
}
```
⇒allprojects内のgoogle()は、なかった場合に追加する

```android/app/build.gradle
dependencies {
    ・・・
}
apply plugin: 'com.google.gms.google-services'  // Gradle plugin
```

### FlutterFire プラグインを追加する

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^0.3.0  # add dependency for Firebase Core
```





これでFirebaseを使う準備は整った


# Firestoreと連携
以下のページを参考にFirestoreとの連携を行う
https://pub.dartlang.org/packages/cloud_firestore#-readme-tab-

## firestoreプラグインの追加
```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^0.3.0  # add dependency for Firebase Core
  cloud_firestore: ^0.9.5
```
⇒各種プラグインは以下を参照
　https://firebaseopensource.com/projects/flutter/plugins/

## Firestoreへアクセスするコードを書く
### cloud_firestoreのインポート
```main.dart
import 'package:cloud_firestore/cloud_firestore.dart';
```

### Firestoreからデータを取得し、リストに表示するコード
※参考にしたページのコードほぼそのまま

```main.dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
          appBar: new AppBar(
            title: new Text('FlutterとFirestoreの連携'),
          ),
          body: new TestList()),
    );
  }
}
class TestList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('test').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError)
          return new Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting: return new Text('Loading...');
          default:
            return new ListView(
              children: snapshot.data.documents.map((DocumentSnapshot document) {
                return new ListTile(
                  title: new Text(document['title']),
                  subtitle: new Text(document['content']),
                );
              }).toList(),
            );
        }
      },
    );
  }
}
```

今回は以下のようなデータ構造で試している
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/f394ecad-cd8c-6a06-83fd-b565f177c0fb.png)


# 動かしてみる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/1e6f9c13-a7ff-3172-2673-98b03212909e.png)

## データを追加してみる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/6a36bacf-19f2-bd2f-ddc3-6d36aa6cc2a6.png)
　↓ データを追加したら、ちゃんとリストに出てきた
![image.png](https://qiita-image-store.s3.amazonaws.com/0/325108/0253aba4-ab1f-72b8-68f0-ed7900299dd8.png)

# まとめ
Flutter、FirebaseともにGoogleが提供しているだけあって、連携はすごく簡単に出来た。
ドキュメントも充実しているため、特に苦労することもなかったと思う。

まだWidgets周りが良く分かってないので、今後はその辺も勉強していこうと思う。



今回作ったものはGitHubに置いてます
https://github.com/teracy55/flutter-firestore