StreamProvider
Streamを作成し、最新のイベントを公開するProvider。
作成された値がFutureではなくStreamである点を除いて、FutureProviderと同じように使用できます。
例えば、 Firebase Cloud Firestore で取得できる snapshot
は Streamなのでこちらを使用することになります。
Firebase Cloud Firestore での使用例
Firestoreでコレクションやドキュメントのスナップショットを得ると、Streamとして取得できます。
一例として、FirestoreからSnapshot(Stream)を取得する記述例です。
// `items`コレクションのスナップショットを取得
final snapshots = FirebaseFirestore.instance
.collection('items')
.snapshots(); // `.get()` だとStreamではなく、Futureになります。
Providerの宣言
StreamProviderを使用して、Firestoreから取得したStreamを返すには以下のように書きます。
Firestoreから取得したデータの型が Map<String, dynamic>
なので、
以下の例では、Itemクラスの fromJson
コンストラクタを使用する想定です。
final itemsStreamProvider = StreamProvider<List<Item>>((ref) {
// users/{user.uid} ドキュメントのSnapshotを取得
final collection = FirebaseFirestore.instance.collection('items');
// データ(Map型)を取得
final stream = collection.snapshots().map(
// CollectionのデータからItemクラスを生成する
(e) => e.docs.map((e) => Item.fromJson(e.data())).toList(),
);
return stream;
});
Widgetからの利用
Widgetからの利用方法は FutureProvider
と同じです。
Futureでは、結果としてデータを受け取っておしまいですが、Streamでは、断続的に更新された最新の値を受け取ることができます。
Widget build(BuildContext context, ScopedReader watch) {
// StreamProviderを読み取る(取得できる型は `AsyncValue<T>`)
final items = watch(itemsStreamProvider);
return Scaffold(
// AsyncValue は `.when` を使ってハンドリングする
body: items.when(
// 処理中は `loading` で指定したWidgetが表示される
loading: () => const CircularProgressIndicator(),
// エラーが発生した場合に表示されるWidgetを指定
error: (error, stack) => Text('Error: $error'),
// 取得した `items` が `data` で使用できる
data: (items) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(title: Text(item.name));
}
)
}
),
);
}
FutureProviderと同じく、 loading
error
状態時のハンドリングが不要の場合は、
data?.value
を使って簡略化することができます。
Widget build(BuildContext context, ScopedReader watch) {
// FutureProviderを読み取る(取得できる型は `AsyncValue<T>?`)
final items = watch(itemsStreamProvider).data?.value;
// Nullチェックは必要
if (items == null) {
return const SizedBox();
}
return Scaffold(
body: Text(items.first.name);
);
}
参考リンク
StreamProvider | Riverpod公式ドキュメントページ