- コレクション名:
items - データ変更をリアルタイムで UI に反映したい
モデルクラスの定義
Firestore のドキュメントを Dart オブジェクトに変換する fromFirestore を用意します。
import 'package:cloud_firestore/cloud_firestore.dart';
class ShoppingItem {
final String id;
final String name;
final String category;
final String createdBy;
DateTime? lastUpdatedAt;
bool isChecked;
ShoppingItem({
required this.id,
required this.name,
required this.category,
required this.createdBy,
this.lastUpdatedAt,
this.isChecked = false,
});
factory ShoppingItem.fromFirestore(
QueryDocumentSnapshot<Map<String, dynamic>> doc,
) {
final data = doc.data();
return ShoppingItem(
id: doc.id,
name: data['name'] ?? '',
category: data['category'] ?? '',
createdBy: data['createdBy'] ?? '',
lastUpdatedAt: (data['lastBoughtAt'] as Timestamp?)?.toDate(),
isChecked: data['isChecked'] ?? false,
);
}
}
StreamBuilder でリアルタイム取得
.snapshots() を使うと、Firestore のデータ変更が自動的に UI に反映されます。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection('items')
.snapshots(),
builder: (context, itemSnapshot) {
// ローディング中
if (!itemSnapshot.hasData) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
// ドキュメント → モデルに変換
final items = itemSnapshot.data!.docs
.map((doc) => ShoppingItem.fromFirestore(doc))
.toList();
// items を使ってリスト表示
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(title: Text(item.name));
},
);
},
)
1件だけ取得したい場合
final doc = await FirebaseFirestore.instance
.collection('items')
.doc('ドキュメントID')
.get();
if (doc.exists) {
final data = doc.data()!;
print(data['name']);
}
条件付き取得
チェック済みアイテムだけ取得する例:
final snapshot = await FirebaseFirestore.instance
.collection('items')
.where('isChecked', isEqualTo: true)
.get();
final checkedItems = snapshot.docs
.map((doc) => ShoppingItem.fromFirestore(doc))
.toList();
.snapshots()→リアルタイム監視→StreamBuilderと相性が良い
fromFirestoreで変換ロジックを1箇所にまとめると保守しやすい
?? '' や ?? false で null 安全にデフォルト値を設定する
買い物リストのように「誰かが追加・更新したら即座に反映したい」場合は.snapshots() + StreamBuilderが定番です。モデルクラスのfromFirestoreを用意しておくと、UI 側のコードがすっきりします。