Firebase Database Rest API 排序字段仅一项值不同时返回结果错误
问题根因
Firebase Realtime Database 存在默认二次排序规则:当你指定的排序字段值存在重复时,系统会自动以节点key的字典序作为第二排序条件完成排序,该规则不可自定义修改。
你的查询逻辑问题点如下:
- 调用
orderBy("Views").limitToLast(10)时,系统先按Views值升序排序,Views值越大的节点位置越靠后,所以Views=50的节点位于排序结果的最末尾。剩余9条返回结果是所有Views=20的节点中,key字典序最大的9个,加起来刚好10条,所以首次查询结果符合预期。 - 第二次分页调用
endAt(50, "-Mn7-ZxkUPO01ifddhtpEn").limitToLast(11)时,endAt会定位到排序结果中「Views值<=50,且key<=-Mn7-ZxkUPO01ifddhtpEn」的位置,再从该位置往前取11条数据。此时Views=20的节点里,key字典序最大的9个(也就是你第一次查询已经拿到的9条)刚好位于50节点的前方,所以会被一同取出,导致重复数据出现。
该问题仅在排序字段大量重复时触发的原因是:如果排序字段值唯一,每个排序值仅对应1条数据,endAt定位后往前取不会包含已查询过的节点,不会出现重复。
修复方案
你可以选择以下任意一种方案解决分页重复问题:
方案1:调整分页参数获取逻辑
- 首次查询后,除了记录最大Views值和对应key,额外记录当前页所有Views=20的节点中key字典序最小的节点的key
- 第二次分页查询时,将参数修改为
orderBy("Views").endAt(20, "刚才记录的最小key").limitToLast(6),即可返回你预期的6条无重复数据
方案2:新增唯一排序字段规避重复
- 给每个节点新增一个唯一排序字段,比如命名为
SortViews,值拼接为[999999 - 实际Views值]_[节点key](用999999减Views是为了升序排序该字段时,等价于Views倒序) - 后续直接按
SortViews字段排序分页,因为该字段值完全唯一,不会出现重复分页问题,也不需要额外处理二次排序逻辑。
内容的提问来源于stack exchange,提问作者OLIVER
相关产品推荐
相关产品推荐

