从Firebase读取数据时遇反序列化异常:期望Map却得到Long
解决Firebase反序列化错误:Expected a Map while deserializing, but got a class java.lang.Long
这个错误的核心原因很明确:你的FBOrganisation模型类中定义的created_on字段是Map<String, String>类型,但Firebase数据库中对应的created_on字段实际存储的是Long类型的时间戳(或者其他非Map结构),导致反序列化时类型不匹配。
步骤1:确认Firebase数据库中的created_on类型
先检查你的Firebase数据库快照,看看created_on字段的值是数字(比如1716182400000这样的时间戳)还是一个包含子字段的Map结构。这是问题的根源。
步骤2:根据实际存储类型修改模型类
情况A:created_on存储的是时间戳(Long类型)
如果数据库里created_on是Unix时间戳,直接修改模型类的字段类型:
public class FBOrganisation { private String name; private String address; private String admin_email; private String subscription_type; private Boolean is_active; private String state; private String pin_code; private String id; private Long created_on; // 将Map<String,String>改为Long // 保留完整的getter、setter方法及@Exclude注解的toMap方法 }
情况B:你本意是存储Map类型的created_on
如果你的需求是让created_on包含多个子字段(比如年、月、日),那要检查写入数据时的代码,确保fbOrganisation的created_on属性被正确赋值为Map,而不是直接传入了时间戳:
// 正确构建Map类型的created_on Map<String, String> createdOnMap = new HashMap<>(); createdOnMap.put("year", String.valueOf(Calendar.getInstance().get(Calendar.YEAR))); createdOnMap.put("month", String.valueOf(Calendar.getInstance().get(Calendar.MONTH) + 1)); createdOnMap.put("day", String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_MONTH))); // 赋值给FBOrganisation对象 fbOrganisation.setCreated_on(createdOnMap); // 再写入Firebase organisations.push().setValue(fbOrganisation, new DatabaseReference.CompletionListener() { @Override public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { if(databaseError == null){ databaseReference.child("id").setValue(databaseReference.getKey()); } } });
步骤3:兼容已存在的旧数据(可选)
如果数据库中已经有部分数据的created_on是Long类型,部分是Map,或者你不想修改模型类,可以手动解析数据来避免错误:
@Override public void onDataChange(DataSnapshot dataSnapshot) { if (dataSnapshot.exists()) { for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){ FBOrganisation anOrganisation = new FBOrganisation(); // 手动逐个解析字段 anOrganisation.setName(singleSnapshot.child("name").getValue(String.class)); anOrganisation.setId(singleSnapshot.child("id").getValue(String.class)); // 处理created_on的类型兼容 Object createdOnValue = singleSnapshot.child("created_on").getValue(); if(createdOnValue instanceof Long){ // 如果是时间戳,可以转成包含timestamp字段的Map Map<String, String> tempMap = new HashMap<>(); tempMap.put("timestamp", createdOnValue.toString()); anOrganisation.setCreated_on(tempMap); } else if(createdOnValue instanceof Map){ anOrganisation.setCreated_on((Map<String, String>) createdOnValue); } // 解析其他字段... Log.d("TAG15",anOrganisation.getName()); Log.d("TAG15",anOrganisation.getId()); } } }
总结
最直接的解决方案就是让模型类的字段类型和Firebase数据库中实际存储的类型完全匹配,这样Firebase的序列化/反序列化机制就能正常工作。
内容的提问来源于stack exchange,提问作者TechBee
相关产品推荐
相关产品推荐

