Kotlin中如何正确从Firebase实时数据库获取嵌套数据结构?
解决Firebase实时数据库类型转换异常的问题
首先直接点出问题根源:你遇到的com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.HashMap to String错误,核心原因是你的User类里submittedRequests字段被定义成了String类型,但数据库中这个字段实际存储的是HashMap(或者列表/集合类结构),Firebase没法把哈希结构强转成字符串,自然就抛出崩溃了。
解决步骤
1. 先确认数据库实际结构
先去Firebase控制台查看submittedRequests的存储形式:
- 如果是多个请求ID的集合(比如
["req001", "req002"]),那它是字符串列表类型; - 如果是包含请求详情的键值对(比如
{"req001": {"content": "代取快递"}, "req002": {"content": "帮忙买咖啡"}}),那它是哈希映射类型。
2. 修改User类的字段类型,匹配数据库结构
根据数据库的实际存储结构,调整User类的submittedRequests字段类型:
情况1:数据库里是字符串列表(请求ID集合)
把字段改成List<String>并设置默认空列表:
class User( val userId: String = "", val name: String = "", val surname: String = "", val profileImageUrl: String = "", val submittedRequests: List<String> = emptyList(), val pickedUpRequests: String = "" // 如果这个字段也存在同样问题,记得同步调整 )
情况2:数据库里是请求对象的哈希映射
先定义一个对应请求结构的数据类(根据你的实际字段调整):
data class Request( val requestId: String = "", val requestContent: String = "", val createTime: Long = 0 // 示例字段,按数据库实际内容添加 )
再把User类里的submittedRequests改成Map<String, Request>:
class User( val userId: String = "", val name: String = "", val surname: String = "", val profileImageUrl: String = "", val submittedRequests: Map<String, Request> = emptyMap(), val pickedUpRequests: String = "" )
3. 额外注意事项
- 如果数据库字段名和类里的驼峰命名不一致(比如数据库是
submitted_requests,类里是submittedRequests),需要添加@PropertyName注解做映射:@PropertyName("submitted_requests") val submittedRequests: List<String> = emptyList() - 确保数据类都有默认值(你现在已经设置了,这点没问题),Firebase需要空参构造能力来解析数据。
4. 原获取代码无需大幅修改
调整完User类后,你原来的监听代码可以直接使用,Firebase会自动把数据库结构解析成你定义的类对象:
userRef.addValueEventListener(object : ValueEventListener { override fun onCancelled(p0: DatabaseError) { // 建议添加错误日志,方便后续排查问题 Log.e("FirebaseError", "数据获取失败: ${p0.message}") } override fun onDataChange(snapshot: DataSnapshot) { if(snapshot.exists()){ val children = snapshot.children userData.clear() // 先清空旧数据,避免重复添加 for(item in children) { val retrieveUser = item.getValue(User::class.java) retrieveUser?.let { userData.add(it) } } // 此处可通知UI更新数据 } } })
内容的提问来源于stack exchange,提问作者Kadir Saglam
相关产品推荐
相关产品推荐

