Flutter 使用 Stream 检索 Firestore 集合
Posted
技术标签:
【中文标题】Flutter 使用 Stream 检索 Firestore 集合【英文标题】:Flutter Retrieving firestore collection using Stream 【发布时间】:2021-04-04 03:17:47 【问题描述】:我正在尝试使用StreamBuilder
在firestore
中检索整个集合,但我陷入了根据我的飞镖模型映射结果的过程中
这是飞镖模型thread.dart:
class Thread
final String threadTitle;
final String threadContent;
final String threadFlair;
final String threadTimestamp;
final List<String> threadLikedBy;
final List<String> originalPoster;
Thread(
this.threadTitle,
this.threadContent,
this.threadTimestamp,
this.threadFlair,
this.threadLikedBy,
this.originalPoster,
);
factory Thread.fromMap(Map<String, dynamic> map) => Thread(
threadTitle: map["threadTitle"],
threadContent: map["threadContent"],
threadFlair: map["threadFlair"],
threadTimestamp: map["threadTimestamp"],
threadLikedBy: List<String>.from(map["threadLikedBy"].map((x) => x)),
originalPoster: List<String>.from(map["originalPoster"].map((x) => x)),
);
Map<String, dynamic> toMap() =>
"threadTitle": threadTitle,
"threadContent": threadContent,
"threadFlair": threadFlair,
"threadTimestamp": threadTimestamp,
"threadLikedBy": List<dynamic>.from(threadLikedBy.map((x) => x)),
"originalPoster": List<dynamic>.from(originalPoster.map((x) => x)),
;
这是我在列表视图中显示结果的小部件:
class _ThreadsBodyState extends State<ThreadsBody>
final threads = _mThreadService.retriveData(path: "posts", builder: (data) => Thread.fromMap(data));
@override
Widget build(BuildContext context)
return Container(
child: StreamBuilder<Object>(
stream: threads,
builder: (context, snapshot)
if (snapshot.hasData)
return ListView.builder(
itemBuilder: (BuildContext context, int index)
Thread thrd = (snapshot.data as List)[index];
return ThreadCard(thread: thrd,);
,
);
else return Text('no data');
),
);
这里是 posts_service.dart 我有 Stream 功能的地方
//After restructuring my model and adding:
//List<String> threadLikedBy; and List<String> originalPoster;
//this method works no more
Stream<List<T>> retrieveData<T>(
@required String path,
@required T builder(Map<String, dynamic> data),
)
final reference = firestoreInstance.collection(path);
final snapshots = reference.snapshots();
return snapshots.map((snapshot) => snapshot.docs.map((snapshot) => builder(snapshot.data())).toList());
似乎我弄乱了返回中的映射,但我无法完全弄清楚如何修复它。
【问题讨论】:
您有必要收听实时数据吗?您似乎正在处理新闻提要部分中的帖子,如果是这种情况,请告诉我,以便我提供解决方案/解决方法。 @ThorvaldOlavsen 是的,这就是我想要做的,但你不认为这些帖子应该是实时的吗? 您可以在用户滚动和刷新时加载数据,当用户位于列表的最顶部并下拉时。 @ThorvaldOlavsen 你能提供你的解决方案,以便我可以尝试实施它吗? 【参考方案1】:在您的“posts_services.dart”中添加以下函数:
Future<QuerySnapshot> fetchThreads() async
return await firestoreInstance.collection('posts').get();
现在在您构建 ListView
的小部件中应该如下所示:
class _ThreadsBodyState extends State<ThreadsBody>
@override
Widget build(BuildContext context)
return Container(
child: FutureBuilder<QuerySnapshot>(
future: youService.fetchThreads(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot)
if (snapshot.hasData)
return ListView.builder(
itemCount: snapshot.data.size, //to retrieve the size
itemBuilder: (BuildContext context, int index)
Thread thrd = Thread.fromMap(snapshot.data.docs[index].data());
return ThreadCard(thread: thrd,);
,
);
else return Text('no data');
),
);
【讨论】:
成功了!虽然我必须重新考虑是保持原样还是切换回实时以上是关于Flutter 使用 Stream 检索 Firestore 集合的主要内容,如果未能解决你的问题,请参考以下文章
如何通过使用flutter bloc从fire存储中使用依赖注入来处理错误`The getter was called on null`
从 Stream 检索快照时,Flutter/Firestore 返回类型 List<Review> 不是“Map<String, dynamic>”类型的子类型