🔥

Firestoreのクエリを使ってみる

2023/02/19に公開2

実行するとどんな動作をするのか?

QuerySnapshotを使ってみる。

公式によると

クエリーの結果を含む。0個以上のDocumentSnapshotオブジェクトを含むことができる。
https://pub.dev/documentation/cloud_firestore/latest/cloud_firestore/QuerySnapshot-class.html

userコレクションに対して実行する.

ElevatedButton(
onPressed: () async {
  await FirebaseFirestore.instance
      .collection('user')
      .get()
      .then((QuerySnapshot querySnapshot) {
    querySnapshot.docs.forEach((doc) {
      print(doc.reference.id);
      print(doc["name"]);
      print(doc["age"]);
    });
  });
},
child: Text('テスト'))

実行結果

userコレクションから、全てのドキュメントid、name、ageフィールドを取得できた。

FmGs0wXy4mYMsZrfCejV
Taro
28
iZW1LXD9T9sxgDRMHAY9
Satou
25
mMPfLxR9TJug0ni9Fan7
Hanako
19
uNGnaOm1CLK34xnZQI0a
fen
20

ちなみにfor文でも同じことが出来ました!

ElevatedButton(
onPressed: () async {
  await FirebaseFirestore.instance
      .collection('user')
      .get()
      .then((QuerySnapshot querySnapshot) {
    for (final doc in querySnapshot.docs) {
      print(doc.reference.id);
      print(doc['name']);
      print(doc['age']);
    }
  });
},
child: Text('テスト'))

実行結果

FmGs0wXy4mYMsZrfCejV
Taro
28
iZW1LXD9T9sxgDRMHAY9
Satou
25
mMPfLxR9TJug0ni9Fan7
Hanako
19
uNGnaOm1CLK34xnZQI0a
fen
20

DocumentSnapshotを使ってみる
どんなものか?
DocumentSnapshotには、FirebaseFirestoreデータベース内のドキュメントから読み込まれたデータが含まれています。

データは、data プロパティで抽出するか、添え字構文を使って特定のフィールドにアクセスすることができます。

こちらが公式
https://pub.dev/documentation/cloud_firestore/latest/cloud_firestore/DocumentSnapshot-class.html
https://firebase.flutter.dev/docs/firestore/usage
FlutterFireの解説の方がわかりやすいかも

DocumentSnapshot は、クエリや、ドキュメントへの直接アクセスによって返されます。データベースにドキュメントが存在しない場合でも、スナップショットは常に返されます。

ドキュメントが存在する場合は、dataメソッドを呼び出すことでそのデータを読み出すことができます。dataメソッドはMap<String, dynamic>を返し、存在しない場合はnullを返します。

ハードコーディングになっちゃいますけど、一致したドキュメントIDのデータを取得できます。

ElevatedButton(
onPressed: () async {
  FirebaseFirestore.instance
      .collection('user')
      .doc('iZW1LXD9T9sxgDRMHAY9')
      .get()
      .then((DocumentSnapshot documentSnapshot) {
    if (documentSnapshot.exists) {
      final data =
	  documentSnapshot.data() as Map<String, dynamic>;
      print(data['name']);
      print(data['age']);
    } else {
      print('Document does not exist on the database');
    }
  });
},
child: Text('テスト'))

実行結果
一致したユーザーの名前と年齢のデータを取得できました。

Satou
25

よく聞くクエリを使ってみる

FlutterFireの内容を翻訳

Querying
Cloud Firestoreは、コレクションへのクエリのための高度な機能を提供します。クエリーは、1回限りの読み取りと変更の購読の両方で動作します。

Filtering
コレクション内のドキュメントをフィルタリングするために、 where メソッドをコレクション参照に連結することができる。フィルタリングは、等号チェックと "in" クエリをサポートしています。たとえば、年齢が 20 歳以上のユーザーを絞り込むには、以下のようにします。

ElevatedButton(
onPressed: () async {
  FirebaseFirestore.instance
      .collection('user')
      .where('age', isGreaterThan: 20)
      .get()
      .then((value) {
    value.docs.forEach((doc) {
      print(doc.reference.id);
      print(doc['name']);
      print(doc['age']);
    });
  });
},
child: Text('テスト'))

実行結果
20歳以上と書いてあったのですが、20歳を超える数値のデータしか取得できていませんでした!
翻訳が間違えているのかも???

iZW1LXD9T9sxgDRMHAY9
Satou
25
FmGs0wXy4mYMsZrfCejV
Taro
28

for文でも同じ結果を実行できる

ElevatedButton(
onPressed: () async {
  FirebaseFirestore.instance
      .collection('user')
      .where('age', isGreaterThan: 20)
      .get()
      .then((value) {
    for (final doc in value.docs) {
      print(doc.reference.id);
      print(doc['name']);
      print(doc['age']);
    }
  });
},
child: Text('テスト'))

実行結果
20歳を超える人物の情報だけ習得できました!

iZW1LXD9T9sxgDRMHAY9
Satou
25
FmGs0wXy4mYMsZrfCejV
Taro
28

まとめ

クエリの種類は多くて、FlutterFireにも載ってないものがあるので結構厄介ですね。
Firebaseのドキュメントは日本語化されたのもあるのですけど、チュートリアルもやらないと分かりにくいですね。
https://cloud.google.com/firestore/docs/how-to?hl=ja

Discussion