Firestore 集合查询作为颤动中的流
Posted
技术标签:
【中文标题】Firestore 集合查询作为颤动中的流【英文标题】:Firestore collection query as stream in flutter 【发布时间】:2020-04-11 01:44:12 【问题描述】:我正在尝试从集合中查询一些文档,这个查询应该监听查询文档中所做的更改,所以我需要一个流。我正在关注(在 Dart/Flutter 中)
Stream<List<MatchRequest>> _getNewMatches()
return Collection<MatchRequest>(path: 'requests')
.ref
.where('status', isNull: true)
.where('users', arrayContains: ['$currentUid'])
.orderBy('last_activity')
.snapshots()
.map((list) => list.documents.map(
(doc) => Global.models[MatchRequest](doc.data) as MatchRequest));
(对象 Collection 在其构造函数中设置 ref 的路径,例如:ref = db.collection($path) 并且 map 对结果进行模型)
然后我使用带有stream
的StreamBuilder 调用上面的方法并builder
检查snapshot.hasData。但它一直在加载,snapshot.hasData 一直是假的。我在这里做错了什么?
编辑:
我的 Firestore 安全规则包含:
match /requests/requestId
allow read: if isLoggedIn();
allow write: if isLoggedIn();
删除每个 where
和 orderBy
时,它也找不到任何东西。并且请求集合中存在文档
当尝试从请求集合中仅查询 1 个文档作为流时,他确实找到了结果
是因为我应该向我的 Firestore 索引添加索引吗?但这并不能解决我的第一个问题,即即使没有where
和orderBy
,它也没有得到任何数据
【问题讨论】:
您的第一个问题可能是在您共享的代码上您没有听到任何内容。您有 snapshots() 但之后没有 listen() 。能够监听 Firestore 集合与索引无关,因此您无需担心。 【参考方案1】:我写了一个简单的例子,它似乎就像你正在尝试做的但缺少 listen() 方法:
Firestore.instance.collection('collection')
.where('field', isEqualTo: 'value')
.orderBy('field')
.snapshots()
.listen((QuerySnapshot querySnapshot)
querySnapshot.documents.forEach((document) => print(document));
);
这只是一个示例,说明如何从 Firestore 流中获取数据并将其用于 StreamBuilder:
class _MyHomePageState extends State<MyHomePage>
Stream dataList;
@override
void initState()
dataList = Firestore.instance.collection('collection')
.where('field', isEqualTo: 'value')
.orderBy('field')
.snapshots();
super.initState();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: StreamBuilder(
stream: dataList,
builder: (context, asyncSnapshot)
if(asyncSnapshot.hasError)
return Text('Error: $asyncSnapshot.error');
switch (asyncSnapshot.connectionState)
case ConnectionState.none: return Text('No data');
case ConnectionState.waiting: return Text('Awaiting...');
case ConnectionState.active:
return ListView(
children: asyncSnapshot.data.map((document) => Text(document['value'])),
);
break;
case ConnectionState.done: return ListView(
children: asyncSnapshot.data.map((document) => Text(document['value'])),
);
break;
return null;
),
),
);
【讨论】:
嗨!确实,在查找时,我发现了该 listen 方法。但我不是很明白。我所做的是将 snapshots() 结果作为 Streamsnapshot.data.documents .map((doc) => Global.models[MatchRequest](doc.data) as MatchRequest) .toList();
以上是关于Firestore 集合查询作为颤动中的流的主要内容,如果未能解决你的问题,请参考以下文章
在颤动中使用 REST api 将列表数据发送到云 Firestore 时出错
使用 StreamBuilder 获取 Firestore 文档,其中包含颤动中的地图列表