Kotlin读取Firebase嵌套子节点user/id数据崩溃,该如何解决?
问题原因
- 路径与数据结构不匹配:你代码中硬编码了
.child("id"),如果该路径指向的是单个SermonSection对象而非对象列表,后续遍历snapshot.children会拿到对象的单个属性节点,无法转换为SermonSection类,返回null后你使用!!强转直接触发空指针崩溃。若iOS端是传入动态用户ID作为路径参数,而Kotlin端写死了字符串"id",也会导致读取的路径不存在、结构不匹配。 - 实体类不符合反序列化要求:Firebase Realtime Database 对Kotlin类进行反序列化时,要求类必须有公开的无参构造方法,如果你定义的
SermonSection没有给属性设置默认值,默认不会生成无参构造,反序列化会直接抛出异常。
修复步骤
- 先修改
SermonSection实体类,给属性加默认值生成无参构造:
data class SermonSection( val detailSection: String = "", val sectionTitle: String = "" )
- 根据你的读取需求修改查询逻辑:
场景1:读取所有用户的SermonSection列表
此时不需要加.child("id"),路径直接指向/user节点即可,同时移除强转,空对象跳过即可:
private fun getData() { // 建议提前在onCreate里初始化Adapter,后续只更新数据通知刷新 sectionRecyclerView.adapter = SectionAdapter(sectionArrayList) database = FirebaseDatabase.getInstance().reference.child("user") database.addValueEventListener(object : ValueEventListener { override fun onCancelled(error: DatabaseError) { println("ERROR is --------> $error") } override fun onDataChange(snapshot: DataSnapshot) { sectionArrayList.clear() if (snapshot.exists()){ for (userSnapShot in snapshot.children) { val user = userSnapShot.getValue(SermonSection::class.java) user?.let { sectionArrayList.add(it) } } sectionRecyclerView.adapter?.notifyDataSetChanged() } } }) }
场景2:读取指定ID的单个用户数据
把硬编码的"id"替换为实际的用户ID变量,同时不需要遍历子节点,直接对snapshot做类型转换:
// 传入实际的目标用户ID,不要写死字符串"id" private fun getData(targetUserId: String) { sectionRecyclerView.adapter = SectionAdapter(sectionArrayList) database = FirebaseDatabase.getInstance().reference.child("user").child(targetUserId) database.addValueEventListener(object : ValueEventListener { override fun onCancelled(error: DatabaseError) { println("ERROR is --------> $error") } override fun onDataChange(snapshot: DataSnapshot) { sectionArrayList.clear() if (snapshot.exists()){ val user = snapshot.getValue(SermonSection::class.java) user?.let { sectionArrayList.add(it) } sectionRecyclerView.adapter?.notifyDataSetChanged() } } }) }
内容的提问来源于stack exchange,提问作者Dowon Lee
相关产品推荐
相关产品推荐

