Flutter中Firestore使用不等式过滤后排序报错如何解决
问题原因
这个报错是Firestore内置的查询规则限制导致的:只要在where条件中使用了不等式运算符(包括isNotEqualTo、isGreaterThan、isLessThan等),查询的第一个orderBy排序字段,必须和使用不等式的字段完全相同。你当前对hidingUserId字段用了isNotEqualTo过滤,但是第一个排序字段是stars,不符合规则就会触发报错。
另外你写的stars过滤条件存在语法错误:where('stars', isEqualTo: 0<=5)中的0<=5会被先计算为布尔值true,相当于你在筛选stars等于true的文档,完全不符合你要筛选stars在0到5之间的需求。
可行解决方案
方案1:调整查询顺序符合Firestore规则
按照要求把hidingUserId放在第一个排序位,再按你需要的stars和时间排序,同时修正stars的范围筛选逻辑,示例代码如下:
stream: postRef .where('hidingUserId', isNotEqualTo: firebaseAuth.currentUser?.uid) // 注意这里要取用户uid,不要直接传用户对象 .where('stars', isGreaterThanOrEqualTo: 0) .where('stars', isLessThanOrEqualTo: 5) .orderBy('hidingUserId') // 不等式字段必须放在第一个排序位 .orderBy('stars', descending: false) .orderBy('timestamp', descending: true) .snapshots(),
注意:第一次运行该查询会触发复合索引缺失的报错,复制报错信息里的索引创建链接,到Firebase控制台点击创建即可,等待索引构建完成后查询就能正常运行。
方案2:客户端侧过滤隐藏内容
如果你不希望查询结果先按hidingUserId排序,可以去掉hidingUserId的服务端过滤条件,先按stars和时间排序拉取数据,再在客户端手动过滤掉hidingUserId等于当前用户ID的帖子,适合数据量不大的场景,示例逻辑如下:
// 服务端查询去掉hidingUserId过滤 stream: postRef .where('stars', isGreaterThanOrEqualTo: 0) .where('stars', isLessThanOrEqualTo: 5) .orderBy('stars', descending: false) .orderBy('timestamp', descending: true) .snapshots(), // 客户端监听时过滤 stream.listen((snapshot) { final visiblePosts = snapshot.docs.where((doc) => doc['hidingUserId'] != firebaseAuth.currentUser?.uid).toList(); // 后续处理visiblePosts即可 })
内容的提问来源于stack exchange,提问作者HaKim
相关产品推荐
相关产品推荐

