You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin读取Firebase嵌套子节点user/id数据崩溃,该如何解决?

问题原因

  1. 路径与数据结构不匹配:你代码中硬编码了.child("id"),如果该路径指向的是单个SermonSection对象而非对象列表,后续遍历snapshot.children会拿到对象的单个属性节点,无法转换为SermonSection类,返回null后你使用!!强转直接触发空指针崩溃。若iOS端是传入动态用户ID作为路径参数,而Kotlin端写死了字符串"id",也会导致读取的路径不存在、结构不匹配。
  2. 实体类不符合反序列化要求:Firebase Realtime Database 对Kotlin类进行反序列化时,要求类必须有公开的无参构造方法,如果你定义的SermonSection没有给属性设置默认值,默认不会生成无参构造,反序列化会直接抛出异常。

修复步骤

  1. 先修改SermonSection实体类,给属性加默认值生成无参构造:
data class SermonSection(
    val detailSection: String = "",
    val sectionTitle: String = ""
)
  1. 根据你的读取需求修改查询逻辑:

场景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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 08:36:02