Flutter筛选Firestore中jobBids下contractorUserId匹配登录用户的问题
问题原因
- 你代码的核心错误出在第二个
where筛选的逻辑上:你调用map方法将jobBids数组转为了布尔值数组(每个元素代表对应bid的contractorUserId是否匹配当前登录uid),但你只判断了这个布尔数组的长度是否大于0。只要jobBids数组不为空,这个布尔数组的长度就永远大于0,不管里面有没有true值,所以会返回所有存在jobBids字段的文档,和你预期的筛选逻辑完全不符。
修正方案
客户端侧代码修正
把第二个where里的逻辑替换为any()方法,只要数组内存在任意一个匹配的bid就保留文档:
_jobsCollectionReference.snapshots().listen((jobBidsSnapshot) { if (jobBidsSnapshot.docs.isNotEmpty) { var jobsWithBids = jobBidsSnapshot.docs .map((jobDoc) => JobWithBids.fromMap(jobDoc.data(), jobDoc.id)) .where((mappedItem) => mappedItem.jobBids != null) // 用any方法判断是否存在匹配的投标记录 .where((mappedItem) => mappedItem.jobBids.any((bid) => bid.contractorUserId == loggedInUser.uid) ) .toList(); } });
性能优化建议(可选)
- 目前的实现是拉取全量
jobs文档后在客户端过滤,如果数据量较大时会浪费带宽、查询速度慢。你可以在jobs文档中新增一个冗余数组字段bidderUids,每次新增投标时同步把对应的contractorUserId存入该数组,就可以直接用Firestore服务端查询过滤,无需拉取全量数据:
// 服务端查询示例,直接过滤出当前用户参与投标的job _jobsCollectionReference .where('bidderUids', arrayContains: loggedInUser.uid) .snapshots() .listen((snapshot) { // 直接处理筛选后的结果即可 });
内容的提问来源于stack exchange,提问作者Niklas
相关产品推荐
相关产品推荐

