Flutter✕Firebase(CloudFirestore編)

---
# :book: Flutterの記事を整理し本にしました :book:
https://zenn.dev/kazutxt/books/flutter_practice_introduction

* <font color="red"><b>本稿の記事を含む様々な記事を体系的に整理し本にまとめました</b></font>
* 今後はこちらを最新化するため、<font color="red"><b>最新情報はこちらをご確認くださ</b>い</font>
* 10万文字を超える超大作になっています(笑)

---

# はじめに
## 概要
* FlutterとFirebaseのFireStoreを使って、DBを実装します

## 対象読者
* FlutterでFirebase(mBaaS)によるDB操作を行ってみたい人

## 関連記事
* [Flutter系の記事のまとめ](https://qiita.com/kazutxt/items/524acb1c134015682ccf)
* :film_frames:  [Get to know Cloud Firestore](https://www.youtube.com/watch?v=v_hR4K4auoQ&list=PLl-K7zZEsYLluG5MCVEzXAQ7ACZBCuZgZ&index=1) 

## スタート(前提条件)
* 2020/12/21時点の情報で執筆しています
    * <font color="red">Beta版ということもあり、メソッド名が変更になったり過去の参考文献がそのままで動かない事がよくあります。</font>
    * 逆に今後の正式版までの間に、本稿の情報が古くなる可能性もありますので、ご容赦ください
* flutterの基本概念を理解されているとより理解できると思います。
* Firebaseをflutterで使えるようになるまでの初期設定は省略します。
* NoSQL及びコレクション/ドキュメントについては説明しません。
    * 関連記事の動画を見ていただくと良いかと思います

## ゴール(達成できること)
* flutter✕FirebaseのCloudFireSotreでDB操作ができるようになります

## スコープ外(ふれないもの)
* Cloud FirestoreとRealtime Databaseの違いについては説明しません。
* Queryについては触れません。今回は単純な直接アクセスによる操作を行います

## 開発環境
* flutterWebを用いているため、現時点でbetaのチャンネルを使っています

```  .sh
% flutter --version
Flutter 1.25.0-8.1.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 8f89f6505b (5 days ago) • 2020-12-15 15:07:52 -0800
Engine • revision 92ae191c17
Tools • Dart 2.12.0 (build 2.12.0-133.2.beta)
```

---

# 本編
## 全体像/結論
* FirebaseのCloudFireStoreを設定し、flutterから呼び出すことで実現できます
* データの操作はWeb上からも可能です

## Part1:画面からの操作

### 操作イメージ
* Cloud Firestoreからコレクションを追加を選択し、コレクションとドキュメントとフィールドを入れます
![db1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/6106f41c-ba02-e21f-761b-f3f8e67290a9.png)

* フィールドの追加
![db2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/32acc35c-e8e3-48bf-a3cc-1fdf6604c87c.png)

* ドキュメントの追加と削除
![db3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/887f1187-c5bf-a142-e5ca-d6985f50b7c4.png)

* サブコレクションの追加
![db4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259228/ad884bc2-ebe4-1e2a-9403-568c07802c7b.png)

## Part2:Flutterからの操作

### 操作イメージ

``` pubspec.yml
# 依存関係を記述しておきます
firebase_core: ^0.5.3
cloud_firestore: ^0.14.4
```
* 今回はWeb版で利用するため、index.htmlのjsについても読み込んでおきます

``` index.html
<script src="https://www.gstatic.com/firebasejs/8.2.0/firebase-firestore.js"></script>
```


``` .dart
// 通常のアクセス
FirebaseFirestore.instance
  .collection('testCollection1')
  .doc('testDocument1')
  .get()
  .then((ref) {
    print(ref.get("testField1"));
});

//  docにパスをまとめて書くアクセス。サブコレクションにアクセス
FirebaseFirestore.instance
  .doc('testCollection1/testDocument1/testSubCollection1/testSubDocument1')
  .get()
  .then((ref) {
    print(ref.get("testField1"));
});

// 追加と更新
// 更新はupdateメソッドがあるようですが、setでも既存データがあれば上書きしてくれるようです。
FirebaseFirestore.instance
  .doc('autoCollection1/autoDocument1')
  .set({'autofield': "abcd"});

// addによるドキュメントIDを指定しない追加
// この場合は、ドキュメントIDはハッシュ値が払い出されます
FirebaseFirestore.instance
  .collection('testCollection1')
  .add({'autofield': "xyz"});


// 削除
FirebaseFirestore.instance
  .doc('autoCollection1/autoDocument1')
  .delete();

// 参照だけを取得
// CollectionReferece
CollectionReference collection =
  FirebaseFirestore.instance
    .collection('testCollection1');
// DocumentReference
DocumentReference document = 
  FirebaseFirestore.instance
    .collection('testCollection1')
    .doc("testDocument1");

```

``` merge.dart
//下記のようにしないと、setするたびに過去のデータが消えるので、前データを残したい場合はmergeオプションを付けます
set(data,SetOptions(merge: true));
```
---

# 補足
## 備考
* まとめてドキュメントの情報を取る方法もあるようですが、うまく動きませんでした
    * バージョンを変えたり、オプションを変えたりすると良いというissueがあったのですが、解決せずでした

``` .dart
FirebaseFirestore.instance
  .collection('testCollection1')
  .get()
  .then((QuerySnapshot querySnapshot) => {
    querySnapshot.docs.forEach((doc) {
 })
});

// エラー
Error: [cloud_firestore/unknown] NoSuchMethodError: invalid member on null: 'includeMetadataChanges'

```

## 参考文献
*  [Flutterで始めるアプリ開発|CloudFirestore概要](https://www.flutter-study.dev/firebase/cloud-firestore)
*  [Firebase Cloud Firestoreの使い方](https://qiita.com/subaru44k/items/a88e638333b8d5cc29f2)

## 追記
* 2020/12/21 初稿