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

Android Firebase获取含列表的子节点时出现No setter/field报错如何解决

问题描述

我在尝试从Firebase获取包含列表my_pokemon的子节点trainer_profile时,遇到如下报错:

W/ClassMapper: No setter/field for my_pokemon found on class com.tapmaxalf.poketest.model.TrainerProfile

我的Firebase数据库结构如下:
数据库结构截图
我使用的ValueEventListener代码如下:

private fun getTrainerProfile(userId: String) {
    firebaseDatabase.child("trainer_profile").child(userId)
        .addValueEventListener(object : ValueEventListener {

            override fun onDataChange(snapshot: DataSnapshot) {

                snapshot.getValue(TrainerProfile::class.java).let { trainerProfile ->

                    if (trainerProfile != null) {
                        viewModelScope.launch (Dispatchers.IO){

                            _state.value = state.value.copy(trainerProfile = trainerProfile)

                            userDao.updateTrainerProfile(trainerProfile, userId)

                            canProfileBeAdded(trainerProfile.timeSentToDatabase)

                            addProfileCountdown(trainerProfile.timeSentToDatabase)
                        }
                    }
                }

            }

            override fun onCancelled(error: DatabaseError) {
                updateError(AuthErrors.GenericError.messageResource)
            }

        })
}

我的TrainerProfile数据类定义如下:

data class TrainerProfile(
val trainerName: String = "",
val location: String = "",
val trainerLevel: String = "",
val trainerCode: String = "",
val profileImage: String = "",
val gifts: Boolean = false,
val trade: Boolean = false,
val raid: Boolean = false,
val timeSentToDatabase: Long = 0,
val myPokemon: List<MyPokemon> = emptyList()
)

请问该如何解决上述报错,成功读取包含列表的Firebase子节点数据?


解决方案

这个报错是因为Firebase数据库的字段名和Kotlin数据类的字段名不匹配导致的:数据库里存储的字段是下划线命名的my_pokemon,但数据类里是小驼峰命名的myPokemon,Firebase默认反序列化时会严格匹配字段名,因此找不到对应字段。

修复方法

  1. 添加@PropertyName注解显式映射(最推荐)
    给数据类中不匹配的字段加上Firebase提供的@PropertyName注解,直接指定对应数据库的字段名:
import com.google.firebase.database.PropertyName

data class TrainerProfile(
    val trainerName: String = "",
    val location: String = "",
    val trainerLevel: String = "",
    val trainerCode: String = "",
    val profileImage: String = "",
    val gifts: Boolean = false,
    val trade: Boolean = false,
    val raid: Boolean = false,
    val timeSentToDatabase: Long = 0,
    @PropertyName("my_pokemon")
    val myPokemon: List<MyPokemon> = emptyList()
)

这种方式既符合Kotlin小驼峰的命名规范,又能正确完成字段映射,不会影响其他代码逻辑。
2. 检查MyPokemon类定义
要保证MyPokemon数据类的所有字段都有默认值,这样Firebase才能正确反序列化列表内的对象。如果MyPokemon的字段也存在数据库命名和代码命名不匹配的情况,也要对应添加@PropertyName注解。
3. 替代方案(不推荐)
你也可以直接把数据类的字段名改为my_pokemon和数据库完全一致,但是这种写法不符合Kotlin官方命名规范,后续代码维护成本更高,不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:06:03