Firebase Realtime Database中endAt()返回错误结果如何避免末端重查?
问题原因
你遇到的问题本质是对Firebase Realtime Database的排序规则和endAt方法的作用理解有误,并非查询自动从末尾id=9重新开始:
- 当你调用
orderByChild("country")时,所有节点会先按country字段的字典序升序排列,字段值相同的节点再按节点key(即你数据里的1、2...9)升序排列。按字典序规则,ca < ja < uk < us,所以所有country为ca的节点排序位置本身就在ja节点之前。 endAt("ja", "9")的作用是筛选出排序结果里,截止到「country值为ja、节点key为9」的所有节点,也就是说所有country值小于等于ja的节点都会被纳入查询候选池,并非你以为的只筛选country等于ja的节点。- 你追加了
limitToLast(4)配置,会从候选池里取排序最后的4条数据,刚好符合条件的节点就是id3(ca)、id6(ca)、id2(ja)、id8(ja),和你实际拿到的返回结果完全一致。
解决方案
如果你仅需要查询country值为ja的节点,直接使用equalTo方法即可,不需要使用endAt,修改后的代码如下:
resultObj = await messagesRef .child("test") .orderByChild("country") .equalTo("ja") .limitToLast(4) // 若不需要限制返回数量可删除此行 .once("value");
如果你需要做分页查询(比如基于上次查询的最后一个节点key拉取更早的country=ja的数据),可以给equalTo传入第二个key参数定位分页边界,示例如下:
// 上次查询最后一个节点的key为8,拉取早于该节点的4条ja数据 resultObj = await messagesRef .child("test") .orderByChild("country") .equalTo("ja", "8") .limitToLast(4) .once("value");
内容的提问来源于stack exchange,提问作者Nguyễn Tuấn Kiệt
相关产品推荐
相关产品推荐

