Flutter Firebase双查询实现获取userOne/userTwo均不含当前用户的数据
问题原因
你当前的实现存在逻辑交集问题:
- streamOne返回所有
jobState=1且userOne≠当前用户的文档,会包含「userTwo是当前用户」的文档 - streamTwo返回所有
jobState=1且userTwo≠当前用户的文档,会包含「userOne是当前用户」的文档
两个流合并后,只要满足任意一个条件的文档都会被输出,自然会返回当前用户存在于userOne或userTwo字段的结果。
修复方案
分两步调整即可达到需求:
- 合并两个流的查询结果后先做文档去重,避免同一份文档被两个流重复返回
- 对合并后的结果做二次过滤,仅保留同时满足
userOne≠当前用户且userTwo≠当前用户的文档
完整实现代码如下:
// 提前获取当前用户uid,避免重复调用可能出现的空安全问题 final currentUid = FirebaseAuth.instance.currentUser?.uid; if (currentUid == null) { // 可自行处理用户未登录场景,比如返回空流 return const Stream.empty(); } var streamOne = FirebaseFirestore.instance .collection('jobs') .where('jobState', isEqualTo: 1) .where('userOne', isNotEqualTo: currentUid) .snapshots(); var streamTwo = FirebaseFirestore.instance .collection('jobs') .where('jobState', isEqualTo: 1) .where('userTwo', isNotEqualTo: currentUid) .snapshots(); // 用RxDart合并流并过滤数据 final filteredJobsStream = CombineLatestStream.combine2( streamOne, streamTwo, (QuerySnapshot snap1, QuerySnapshot snap2) { // 用文档ID做去重 final docMap = <String, QueryDocumentSnapshot>{}; for (var doc in snap1.docs) docMap[doc.id] = doc; for (var doc in snap2.docs) docMap[doc.id] = doc; // 二次过滤符合要求的文档 return docMap.values.where((doc) { final jobData = doc.data() as Map<String, dynamic>; return jobData['userOne'] != currentUid && jobData['userTwo'] != currentUid; }).toList(); } );
可选优化方案
如果你的jobs数据量较大,不想在客户端做二次过滤,可以在写入jobs文档时新增一个relatedUsers数组字段,把userOne和userTwo的uid都存入该数组,之后直接用单个查询就能拿到结果,不需要合并流:
final filteredJobsStream = FirebaseFirestore.instance .collection('jobs') .where('jobState', isEqualTo: 1) .where('relatedUsers', whereNotIn: [currentUid]) .snapshots();
内容的提问来源于stack exchange,提问作者beax07
相关产品推荐
相关产品推荐

