[英]Firestore collection query as stream in flutter
I'm trying to query a few documents from a collection, this query should listen to changes made in the queried documents, so I'd need a stream. I'm doing following (in Dart/Flutter)我正在尝试从集合中查询一些文档,此查询应该监听查询文档中所做的更改,因此我需要一个 stream。我正在执行以下操作(在 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));
}
(The object Collection sets the path to the ref in it's constructor, eg: ref = db.collection($path) and the map makes a model of the results) (object Collection 在其构造函数中设置 ref 的路径,例如:ref = db.collection($path) 和 map 生成结果的 model)
Then I'm using a StreamBuilder with stream
invoking the method above and builder
checking if snapshot.hasData.然后我使用带有 stream 的
stream
调用上面的方法和builder
检查是否 snapshot.hasData。 But it keeps loading, snapshot.hasData keeps being false.但它一直在加载,snapshot.hasData 一直是错误的。 What am I doing wrong here?
我在这里做错了什么?
EDIT:编辑:
My firestore security rules contain:我的 Firestore 安全规则包含:
match /requests/{requestId} { allow read: if isLoggedIn(); allow write: if isLoggedIn(); }
When removing every where
and orderBy
, it doesn't find anything as well.当删除每个
where
和orderBy
,它也找不到任何东西。 And there are documents present in the requests-collection并且请求集合中存在文档
When trying to query only 1 document as a stream from the requests-collection, he does find the result当试图从请求集合中仅查询 1 个文档作为 stream 时,他确实找到了结果
Is it because I should add indexes to my firestore indexes?是因为我应该将索引添加到我的 firestore 索引中吗? But this won't solve my first problem which is that even without
where
and orderBy
, it doesn't get any data但这并不能解决我的第一个问题,即即使没有
where
和orderBy
,它也得不到任何数据
I've written a simple example of it seems to be like what you are trying to do but are missing the listen() method:我写了一个简单的例子,它似乎就像你想要做的,但缺少 listen() 方法:
Firestore.instance.collection('collection')
.where('field', isEqualTo: 'value')
.orderBy('field')
.snapshots()
.listen((QuerySnapshot querySnapshot){
querySnapshot.documents.forEach((document) => print(document));
}
);
This is just an example of how you can take the data from a Firestore Stream and use it on a StreamBuilder:这只是一个示例,说明如何从 Firestore Stream 获取数据并在 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;
}),
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore
.instance.
.collection('users') // 👈 Your desired collection name here
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['fullName']), // 👈 Your valid data here
);
}).toList());
},
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore
.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid) // 👈 Your document id change accordingly
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Loading");
}
Map<String, dynamic> data =
snapshot.data!.data()! as Map<String, dynamic>;
return Text(data['fullName']); // 👈 your valid data here
},
),
),
);
}
Also refer: How to use StreamBuilder
and FutureBuilder
for single and multiple documents另请参阅: How to use
StreamBuilder
and FutureBuilder
for single and multiple documents
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.