【Flutter・Firebase】Firestoreの基本(登録・更新・取得・削除)をサンプルで紹介!

どーも、ぐるたか@guru_takaです。

Flutterにて、Firestoreでよく使う関数をまとめておきます。いわゆる、チートシートです!

  • 登録
  • 更新
  • 削除
  • 取得

FlutterにFirestoreを導入する手順はこちらの記事にまとめているので、参考にしてみてください!

登録

void setData(String collection, Map data) {
 Firestore.instance.collection(collection).document().setData(data);
}

Map方のデータは、以下の通りです。

Map<String, dynamic> data = {
  "field名": "登録するデータ",
};
サンプル
Map<String, dynamic> data = {
  "title": "テスト",
  "createdAt": DateTime.now(),
};

更新

void updateData(String collection, String documentID, Map data) {
  Firestore.instance.collection(collection).document(documentID).updateData(data);
}

collectiondocumentIDを指定し、更新したいデータのみupdateできます。

削除

void deleteData(String collection, String documentId) {
  Firestore.instance.collection(collection).document(documentId).delete();
}

collectiondocumentIDを指定すれば、簡単に削除できます。

取得

Firestoreの大枠をイメージできておくと、様々なデータを取得する関数の理解が捗ります。

  • collection:documentの集まり
  • document:dataの集まり

そのため、collection.getDocuments()document.get()の関数で大きな違いがあるんです。

  • collection.get():返り値の型はQuerySnapshot
  • document.getDocuments():返り値の型はDocumentSnapshot

collection.get()の場合、documentの集まりを取得できます。そのため、QuerySnapshot.documents[0].data()で初めてデータにアクセス可能。

QuerySnapshot.data()ではデータの取得はできないので、注意してください!

一方で、document.get()の場合、document、つまりデータの集まりを取得できるので、DocumentSnapshot.data()で直接データにアクセスできます。

参考 Firebase Cloud Firestoreの使い方Qiita

document取得

Future<Map<String, dynamic>> getData(String collection, String documentId) async {
  DocumentSnapshot docSnapshot =
      await Firestore.instance.collection(collection).document(documentId).get();

  return docSnapshot.data;
}
サンプル
特定のフィールドのデータを取得したい場合は、以下みたいになります!
Future<String> getData(String collection, String documentId,String field) async {
  DocumentSnapshot docSnapshot =
      await Firestore.instance.collection(collection).document(documentId).get();
  Map<String, dynamic> record = docSnapshot.data;
  return record[field];
}

document一覧を取得

Future<QuerySnapshot> getDocuments(String collection) async {
  return await Firestore.instance.collection(collection).getDocuments();
}

Streamのsnapshotを取得

Stream<QuerySnapshot> getStreamSnapshots(String collection)  {
  return Firestore.instance.collection(collection).snapshots();
}

Streamとは、英語で小川という意味です。超簡単にまとめると、Streamに何かしらの値が入ってきたら、自動で処理をやってくれます!

例えば、Firestore内のデータをリストで表示したいとします。そのデータに変更があったら、View側も自動で更新したいですよね。

そんなとき、Streamをつかっていると、データ変更時に自動でView側も更新されます。控えめにいって、超便利です!

参考 長めだけどたぶんわかりやすいBLoCパターンの解説<br /> DartQiita
サンプル
View側で表示したい場合、StreamBuilderを使います。サンプルはこんな感じ!

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('collection').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) return Text("loading");
        return ListView(
          children: snapshot.data.documents.map(
            (doc) {
              return Text(doc.data["title"]);
            },
          ).toList(),
        );
      },
    );
  }

Firestore側からデータを取得できるまでは、Text("loading")を表示。データ取得が完了したら、リストでテキスト一覧を表示してくれます。

Firestore側でデータに変更があれば自動で更新してくれるので重宝するでしょう!
参考 Simple Recipes App made in Flutter — FirestoreMedium

データのソート

クエリに対し、ソートすることも可能です。ここでは、よく使うものを紹介します。

  • where:特定のデータ指定
  • orderBy:昇順、降順
Stream<QuerySnapshot> getStreamSnapshots(String collection) {
  return Firestore.instance
      .collection(collection)
      .where("title", isEqualTo: "test")
      .orderBy('createdAt', descending: true)
      .snapshots();
}

descendingは降順という意味です。昇順にしたい場合は、descending: falseにしましょう!

サンプル
whereでクエリをソートする際に、userIdが絡むuserRefを使う場合が多いかもしれません。その場合は、以下のようになります。
Stream<QuerySnapshot> getStreamSnapshots(String collection, String userRef) {
  final DocumentReference _userRef = Firestore.instance.document(userRef);
  return Firestore.instance
      .collection(collection)
      .where("userRef", isEqualTo: _userRef)
      .orderBy('createdAt', descending: true)
      .snapshots();
}

参考リンク

参考 cloud_firestorepub.dev

2 COMMENTS

ほんだ

大変わかりやすい記事、ありがとうございます!

ひとつ指摘なのですが、「Streamのsnapshotを取得」のサンプルに抜けがあるかと思います。

それは、StreamBuilder とAsyncSnapshotの直後に「」がないことです。

なかったらdoc.documents←これが紫色にならずバグりました。。。

ぐるたか

ご返信、遅くなり、申し訳ございません。
こちら修正いたしました。

ご指摘のほど、ありがとうございます!

また何かございましたら、コメント頂けますと幸いですm(_ _)m

コメントを残す