Flutter如何根据Firestore集合中的数组值过滤数据,排除用户已隐藏的帖子
问题原因与解决方案
你遇到的加载异常、无数据展示的问题完全来自代码逻辑的写法错误,以下是具体问题说明和修正代码:
核心错误点
- 混淆了
Stream.where的用法:Stream.where回调仅接受布尔值返回,用来筛选流中需要向下传递的事件,你之前在回调中返回print语句、Container组件,返回类型完全不匹配,导致流无有效数据输出,页面一直卡在加载状态。 - 判断逻辑语法错误:你写的
event.data()['hidingUserId'].contains(!currentUserId())中感叹号位置错误,相当于把用户ID字符串转成布尔值取反后去匹配数组,永远不可能匹配到有效数据。 - 空状态配置位置错误:无数据提示的组件应该配置在
StreamBuilderWrapper的空状态回调参数中,不能写在流的筛选逻辑里。

修正方案
Firestore目前不支持arrayNotContains服务端查询,所以直接在本地做过滤即可,代码修改如下:
// 流的定义不需要额外加where筛选,保留原始查询即可 Stream streams = postRef .orderBy('stars', descending: false) .orderBy('timestamp', descending: true) .snapshots(); @override Widget build(BuildContext context) { // 提前获取当前用户ID,避免重复调用 final currentUid = currentUserId(); return ListView( shrinkWrap: true, padding: EdgeInsets.symmetric(horizontal: 10.0), children: [ StreamBuilderWrapper( shrinkWrap: true, // 直接传原始流即可 stream: streams, physics: NeverScrollableScrollPhysics(), itemBuilder: (_, DocumentSnapshot snapshot) { internetChecker(); // 先判断当前帖子是否被当前用户隐藏 Map<String, dynamic> postData = snapshot.data() as Map<String, dynamic>; List? hidingUsers = postData['hidingUserId']; // 如果帖子被当前用户隐藏,直接返回空控件不渲染 if (hidingUsers != null && hidingUsers.contains(currentUid)) { return const SizedBox.shrink(); } Review posts = Review.fromJson(postData); return posts.postId != null ? Padding( padding: const EdgeInsets.only(bottom: 12.0), child: Posts(post: posts), ) : const SizedBox.shrink(); }, // 若StreamBuilderWrapper支持emptyBuilder参数,可在这里配置全局无数据提示 emptyBuilder: (context) => const Center( child: Text('Nothing to show'), ), ), ], ); }
如果你希望提前过滤掉隐藏的帖子,也可以对流做转换处理,不需要改动itemBuilder逻辑:
final currentUid = currentUserId(); Stream streams = postRef .orderBy('stars', descending: false) .orderBy('timestamp', descending: true) .snapshots() .map((snapshot) { // 提前过滤掉已被当前用户隐藏的帖子 snapshot.docs = snapshot.docs.where((doc) { List? hidingUsers = doc.data()['hidingUserId']; return hidingUsers == null || !hidingUsers.contains(currentUid); }).toList(); return snapshot; });
内容的提问来源于stack exchange,提问作者HaKim
相关产品推荐
相关产品推荐

