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

解决Firebase DatabaseException:ArrayList转WaitUserModel失败问题

问题:Firebase Realtime Database类型转换异常(ArrayList转WaitUserModel)

异常信息

com.google.firebase.database.DatabaseException: 无法将java.util.ArrayList类型的对象转换为com.example.myapplication.WaitUserModel类型
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:436)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.example.myapplication.CategoryPage$startMatching$1$onDataChange$1.onDataChange(CategoryPage.kt:150)
...(省略中间栈信息)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

相关代码

WaitUserModel.kt

data class WaitUserModel(
    val uid: String,
    var grade: Float?,
    var brands: ArrayList<String>,
    var fail: Int = 0
)
{
    init {
        // 将字符串解析为浮点型并存储到grade字段
        this.grade = grade ?: 0.0f
    }
}

CategoryPage.kt关键代码(startMatching方法)

fun startMatching(selectedBrands: MutableList<String>) {
    // ...省略前面代码
    // 查找匹配等待中的用户
    waitUsersRef.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            for (waitUserSnapshot in snapshot.children) {
                val waitUser = waitUserSnapshot.getValue(WaitUserModel::class.java)

                if (waitUser != null && waitUser.uid != currentUserId && waitUser.brands != null) {
                    // 手动转换brands字段
                    val brands = waitUserSnapshot.child("brands").getValue() as? ArrayList<String>
                    waitUser.brands = (brands ?: ArrayList())

                    val intersection = waitUser.brands.intersect(mySelectedBrands)
                    if (intersection.isNotEmpty()) {
                        // ...省略匹配逻辑
                    }
                }
            }
        }
        override fun onCancelled(error: DatabaseError) {}
    })
    // ...省略其他代码
}

Firebase数据库WaitUsers节点结构

"gLXAaWKYGTdPzceWbrqcQBSA67C3": {
      "brands": [
        "비비큐",
        "지코바"
      ],
      "fail": 0,
      "grade": 0,
      "uid": "gLXAaWKYGTdPzceWbrqcQBSA67C3"
    }

解决方案

1. 修改WaitUserModel的集合类型与构造函数

Firebase反序列化时默认将数组转为java.util.ArrayList,但Kotlin中使用集合接口而非具体实现类能避免类型冲突。同时必须添加无参构造函数(Firebase反序列化的强制要求):

data class WaitUserModel(
    val uid: String,
    var grade: Float?,
    var brands: List<String>, // 改为List接口,适配Firebase自动转换
    var fail: Int = 0
) {
    init {
        this.grade = grade ?: 0.0f
    }
    
    // 添加无参构造函数
    constructor() : this("", 0.0f, emptyList())
}

2. 删除冗余的手动转换代码

修改后Firebase会自动完成brands字段的反序列化,不需要手动获取并赋值,删除以下代码:

// 手动转换brands字段 -> 删除此行及后续赋值
val brands = waitUserSnapshot.child("brands").getValue() as? ArrayList<String>
waitUser.brands = (brands ?: ArrayList())

3. 检查数据库节点完整性

确认WaitUsers节点下的所有子节点都是完整的WaitUserModel结构,不存在直接存储ArrayList的错误节点(比如误将brands数组直接存到WaitUsers根节点下)。


内容的提问来源于stack exchange,提问作者hahahahaya0624

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:47:10