今回はFirestoreからデータの取得方法について紹介します。
Firestorの登録データをリアルタイムに取得して画面に一覧表示します。
Scaffold
メソッドの引数名body:
以降の記述を変更します。
(変更前)
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
(変更後)
body: StreamBuilder<QuerySnapshot>(
stream: users.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text("エラーが発生しました: ${snapshot.error}");
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("読み込み中...");
}
// ドキュメントからデータのリストを作成
List<QueryDocumentSnapshot> usersList = snapshot.data!.docs;
return ListView.builder(
itemCount: usersList.length,
itemBuilder: (context, index) {
// nameフィールドを取得
String username = usersList[index]['name'];
return ListTile(
title: Text(username),
);
},
);
},
),
StreamBuilder<QuerySnapshot>(
//<処理>
)
StreamBuilderを利用すると、ストリームを通じてデータをリアルタイムにUIに反映(再構築)します。そして、<QuerySnapshot>
は、StreamBuilderで取得するFirestoreのデータコレクションの型となります。
StreamBuilder<QuerySnapshot>(
stream: users.snapshots()
//<処理>
)
stream: users.snapshots()
は、QuerySnapshotで取得する対象です。snapshots()
は、指定したコレクション(users
)に対して、ストリームを作成します。コレクション内のドキュメントが追加、削除、変更されるたびに、新しいQuerySnapshot
を発行します。
StreamBuilder<QuerySnapshot>(
stream: users.snapshots()
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
//<処理>
}
)
StreamBuilder
ウィジェットがストリームの新しいイベントを受け取るたびに、新しいAsyncSnapshot
インスタンスがbuilder
関数に渡されウィジェットの構築を行います。
BuildContext context
現在のビルドコンテキストAsyncSnapshot<QuerySnapshot> snapshot
ストリームからの最新のスナップショットを取得して結果を保持します。このsnapshot
オブジェクトを使用して、非同期データに基づいてUIを動的に構築・更新することができます。
この builder
関数内では、通常以下のような処理が行われます。
if (snapshot.hasError) {
return Text("エラーが発生しました: ${snapshot.error}");
}
StreamBuilder
の builder
関数内で一般的に見られるエラーハンドリングの部分です。非同期スナップショットにエラーが含まれているかどうかをチェックします。
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("読み込み中...");
}
StreamBuilder
のbuilder
関数内で非同期データのロード状態を処理しています。特に、データがまだロード中である場合に、ユーザーにローディングメッセージを表示するロジックを提供しています。
snapshot.connectionState
非同期操作の現在の接続状態を表します。ConnectionState.waiting
非同期操作がまだ「進行中」であることを表します。
このようなローディングインジケーターは、ユーザーエクスペリエンスの観点から重要です。非同期データのロード中にアプリケーションが何も反応しないと、ユーザーは混乱するかもしれません。ローディングメッセージを提供することで、何が起こっているのかをユーザーに知らせ、待機している間にもアプリケーションが応答していることを確認させることができます。
List<QueryDocumentSnapshot> usersList = snapshot.data!.docs;
Firestoreから取得したクエリのスナップショットからドキュメントのリストを取得しています。具体的には、クエリスナップショット内のすべてのドキュメントをQueryDocumentSnapshot
のリストとして抽出します。
snapshot.data
:snapshot
オブジェクトは、非同期操作からの最新のスナップショットを表し、data
プロパティを通じてQuerySnapshot
オブジェクトへのアクセスを提供します。このオブジェクトには、クエリに一致するドキュメントの現在の状態が含まれています。!
(バング演算子): この演算子は、data
がnullでないことを保証します。nullの可能性がある場合にこの演算子を使用すると、もし実際にnullであればランタイムエラーが発生します。このコードの文脈では、snapshot.data
がnullでないことを確信しているとみなされます。.docs
:QuerySnapshot
オブジェクトのdocs
プロパティは、クエリに一致するドキュメントのリストを提供します。このリストには、クエリスナップショット内のすべてのドキュメントが含まれ、それぞれがQueryDocumentSnapshot
オブジェクトとして表されます。List<QueryDocumentSnapshot> usersList
: 取得されたドキュメントのリストは、usersList
変数に代入されます。このリストは後続のコードで処理されることが一般的で、例えばリストビューを生成するために使用されることが多いです。
このコードの目的は、Firestoreのクエリから特定のドキュメントの集合を取得し、それらのドキュメントをプログラムで処理できる形式でアクセス可能にすることです。
return ListView.builder(
itemCount: usersList.length,
itemBuilder: (context, index) {
// nameフィールドを取得
String username = usersList[index]['name'];
return ListTile(
title: Text(username),
);
},
);
Firestoreから取得したユーザーリスト(usersList
)を使用して、リストビューを構築しています。具体的には、ListView.builder
ウィジェットを使用して、各ユーザーの名前を表示するリストアイテムを動的に生成しています。
ListView.builder
: Flutterでリストビューを効率的に構築するためのウィジェットです。大量のアイテムを持つリストでも、画面上に表示されるアイテムだけが構築されるため、パフォーマンスが向上します。itemCount: usersList.length
:usersList
の長さ(リスト内のアイテム数)を指定します。これによって、リストビューが何個のアイテムを持つべきかを知ります。itemBuilder: (context, index)
:itemBuilder
は、リストの各アイテムを構築するためのコールバック関数です。この関数はリストの各アイテムのインデックスとともに呼び出され、それに対応するウィジェットを返します。String username = usersList[index]['name'];
:usersList
から指定されたインデックスのユーザーを取得し、そのユーザーのname
フィールドを取り出します。この値は後続のText
ウィジェットで表示されます。return ListTile(title: Text(username),);
:ListTile
ウィジェットは、リスト内の個々のアイテムを表します。ここでは、取得したユーザー名をタイトルとして使用しています。後続のコードでは、このリストアイテムにさらに詳細を追加することができます(例:サブタイトル、先頭アイコンなど)。
全体として、このコードはFirestoreから取得したユーザーデータのリストを取り、それを基にリストビューを構築します。このような動的なリストビューの構築は、多くのモバイルアプリケーションで一般的なパターンであり、Flutterでの実装はこのようになります。