使用orderByChild时addChildEventListener等三类监听器的区别及get()排序问题
Firebase排序相关API使用说明
关于get()是否遵循orderByChild()排序规则的说明
get()方法会严格遵循orderByChild()、orderByKey()等排序方法指定的规则返回数据。你使用get()时排序不生效,几乎都是因为回调中处理DataSnapshot的方式错误:
直接调用
DataSnapshot.getValue()转换为Map/集合类时,由于普通Map本身是无序存储结构,会丢失排序信息,必须通过DataSnapshot.getChildren()迭代子节点,才能获得符合排序规则的结果。
正确的get()使用示例:
ref.child("dinosaurs").orderByChild("height").get().addOnCompleteListener(task -> { if (task.isSuccessful()) { // 遍历getChildren才能保留排序顺序 for (DataSnapshot childSnap : task.getResult().getChildren()) { // 此处获取的子节点就是按height从小到大排序的 Dinosaur dino = childSnap.getValue(Dinosaur.class); } } });
三类监听/获取方法的核心区别
get() + addOnCompleteListener
属于一次性数据拉取接口,仅请求一次数据,不会持续监听数据变更,返回的是查询范围内的完整DataSnapshot对象,适合只需要拉一次数据的场景。addValueEventListener
属于持续监听接口,只要查询范围内的数据发生任何新增、修改、删除操作,都会触发回调,返回查询范围内的完整DataSnapshot对象,和get()返回的结构完全一致,同样需要通过getChildren()迭代获得排序结果,适合需要实时同步全量数据的场景。addChildEventListener
属于子节点级别的持续监听接口,会针对子节点的不同操作分别触发onChildAdded、onChildChanged、onChildRemoved、onChildMoved回调。所有回调都会严格遵循排序规则返回节点位置,比如初始化时会按排序顺序依次触发onChildAdded返回所有子节点,新增子节点时也会按排序位置触发对应回调,不需要额外处理全量集合的顺序,适合需要处理子节点粒度变更的列表场景。
内容的提问来源于stack exchange,提问作者jpizarra
相关产品推荐
相关产品推荐

