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默认反序列化时会严格匹配字段名,因此找不到对应字段。
修复方法
- 添加
@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
相关产品推荐
相关产品推荐

