从 QuerySnapshot 和 Listview Builder (Flutter & Firebase) 中排除文档
Posted
技术标签:
【中文标题】从 QuerySnapshot 和 Listview Builder (Flutter & Firebase) 中排除文档【英文标题】:Exclude documents from QuerySnapshot and Listview Builder (Flutter & Firebase) 【发布时间】:2021-09-16 06:59:52 【问题描述】:我在 Firebase 中收到了一系列问题。类别存储在一个数组中。现在我想隐藏特定问题,如果用户选择隐藏它(用户 ID 存储在另一个名为 hidden 的数组中)。这是我尝试过的:
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("question")
.where('category', arrayContainsAny: [widget.cid])
.where('hidden', '!=', '$user.uid')
// also tried where('hidden', isNotEqualTo: [user.uid])
.snapshots(),
builder: (context, snapshot)
return !snapshot.hasData
? Center(child: CircularProgressIndicator())
: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data!.docs.length,
itemBuilder: (context, index)
DocumentSnapshot data = snapshot.data!.docs[index];
return QuestionList(
de_du: data['de_du'],
de_sie: data['de_sie'],
de_ich: data['de_ich'],
qid: data['id'],
en: data['en'],
id: data.id,
documentSnapshot: data,
);
,
);
,
),
关于如何到达那里有什么建议吗?
更新:
我尝试实现转换。我仍然遇到错误并且无法正常工作。我得到的错误:transform 中的第一个快照未定义。在变换中的第一个快照之后需要一个 )。我还得到了信息,即未使用用户(用户 ID 的提供者)。
class _CategoryDetailState extends State<CategoryDetail>
@override
Widget build(BuildContext context)
var user = Provider.of<AuthProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text(
this.widget.titel,
style: TextStyle(fontFamily: 'Gruppo'),
),
),
body: ListView(
children: [
Card(
margin: EdgeInsets.all(10),
child: Column(
children: [
Image.network(this.widget.image),
ListTile(
title: Text(this.widget.titel),
subtitle: Text(this.widget.description),
),
],
),
),
Center(
child: Text(
'Fragenübersicht:',
style: TextStyle(fontFamily: 'Caveat', fontSize: 25),
),
),
StreamBuilder<List<DocumentSnapshot>>(
stream: FirebaseFirestore.instance
.collection("question")
.where('category', arrayContainsAny: [widget.cid])
.snapshots()
.transform(snapshot => snapshot.docs.where(d => doc.data().hidden.contains(user.userid).toList())),
builder: (context, snapshot)
if (!snapshot.hasData)
return Center(child: CircularProgressIndicator());
else
return ListView.builder(
scrollDirection: Axis.vertical,
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (context, index)
DocumentSnapshot data = snapshot.data![index];
return QuestionList(
de_du: data['de_du'],
de_sie: data['de_sie'],
de_ich: data['de_ich'],
qid: data['id'],
en: data['en'],
id: data.id,
documentSnapshot: data,
);
,
);
,
),
],
),
);
【问题讨论】:
【参考方案1】:无法通过条件从Firestore query 中排除单个项目。您需要的是 array-does-not-contain
条件,它不存在。
这意味着您必须从数据库中读取其他项目,然后使用以下内容将它们从流中排除:
StreamBuilder<List<DocumentSnapshot>>(
stream: FirebaseFirestore.instance
.collection("question")
.where('category', arrayContainsAny: [widget.cid])
.where('hidden', '!=', '$user.uid')
.snapshots()
.transform(snapshot => snapshot.docs.where(d => doc.data().hidden.contains(user.uid)).toList(),
您还需要更新构建器以反映它现在获得List<DocumentSnapshot>
而不是QuerySnapshot
。
【讨论】:
感谢您的回复!因为我对这个很陌生——我仍然没有让它工作..我使用一个列表来完成排除,但我不明白它是如何工作的。如果我得到以下流: stream: FirebaseFirestore.instance .collection("question") .where('category', arrayContainsAny: [widget.cid]) .where('hidden', arrayContainsAny: [user.uid]) 。 snapshots(),.transform() 是如何工作的 List = (data from category-where) - (data from hidden-where) 试图在网上找到更多但没有运气。transform
调用将您从 Firestore 获得的 Stream<QuerySnapshot>
转换为 Stream<List<DocumentSnapshot>>
并过滤与 UID 不匹配的文档 doc.data().hidden.contains(user.uid)
。
我还没有让它工作..首先解决其他挑战..这是我列表中的下一个..将再试一次以完成您已经提供的帮助并会尽快回复您;)
嘿弗兰克,我尝试实现转换。我仍然遇到错误并且无法正常工作。我得到的错误:transform 中的第一个快照未定义。在变换的第一个快照之后需要一个 )。我还得到了信息,即未使用用户(用户 ID 的提供者)。以上是关于从 QuerySnapshot 和 Listview Builder (Flutter & Firebase) 中排除文档的主要内容,如果未能解决你的问题,请参考以下文章
错误:“QuerySnapshot”类没有实例获取器“数据”
我是不是需要取消 Stream<QuerySnapshot> (颤振)
Flutter/Firestore:“QuerySnapshot”类没有实例获取器“document”