Android开发接入Firebase Realtime Database查询返回空对象问题
Firebase Realtime Database查询返回空对象的定位与修复
原实现配置
- 数据库结构示意:

- 原有查询逻辑:
void getLicRequest(String iid) { DatabaseReference ref= FirebaseDatabase.getInstance().getReference("LicenseUpRequests"); Query qu=ref.orderByChild("id").equalTo(iid); qu.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { Commons k=(Commons)getApplicationContext(); k.licRequest=snapshot.getValue(LicenseModel.class); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); }
- 原有数据映射实体类:
public class LicenseModel { public String frontSide; public String backSide; public String id; public String date; public String getFrontSide() { return frontSide; } public void setFrontSide(String frontSide) { this.frontSide = frontSide; } public String getBackSide() { return backSide; } public void setBackSide(String backSide) { this.backSide = backSide; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } }
核心根因
- 查询返回的快照结构与映射目标不匹配
对LicenseUpRequests父节点执行orderByChild().equalTo()查询时,返回的顶层DataSnapshot是所有匹配结果的集合容器,本身不存储LicenseModel对应的字段值。每个匹配的业务数据都嵌套在容器下的随机生成push ID子节点中。直接对顶层快照调用getValue(LicenseModel.class),相当于把Map结构的集合强转成单个实体类,必然返回null。 - 触发反序列化失败的常见场景
Firebase Realtime Database有固定的反序列化规则,不满足规则时也会返回null:- 实体类必须保留无参public构造方法,手动添加带参构造时如果未显式声明无参构造,会直接导致反序列化失败
- 实体类的字段名必须和数据库存储的字段名完全大小写匹配,比如数据库存储的是全小写
frontside,和类里的驼峰frontSide不匹配时,对应字段无法完成映射
修复实现
修改onDataChange内的取值逻辑,遍历顶层快照下的子节点,提取实际匹配的业务数据:
@Override public void onDataChange(@NonNull DataSnapshot snapshot) { Commons k = (Commons) getApplicationContext(); // 遍历查询返回的所有匹配子节点 for (DataSnapshot childSnapshot : snapshot.getChildren()) { LicenseModel licData = childSnapshot.getValue(LicenseModel.class); if (licData != null) { k.licRequest = licData; // 按唯一id查询仅存在一个匹配结果,拿到有效数据后即可跳出循环 break; } } }
注意事项
- 不要将核心业务数据长期存储在继承Application的全局静态对象中,App进入后台被系统回收时,Application实例会被销毁,全局存储的数据会丢失,后续读取时容易触发空指针异常
- 排查数据库安全规则是否允许当前路径的读权限,规则不匹配时查询会直接触发
onCancelled回调,不会拉取到任何数据
内容的提问来源于stack exchange,提问作者Muhammad Aon
相关产品推荐
相关产品推荐

