点击跳转含Firebase数据库的Activity时崩溃返回的解决方案
问题解决方案
错误原因分析
从报错日志Can't convert object of type java.lang.String to type com.example.blood.utilities.User可以明确:Firebase数据库的Users节点下存在非User对象结构的子节点——某个子节点直接存储了字符串值,而非包含name、email等字段的对象,导致读取时类型转换失败。
具体解决步骤
1. 检查并修正Firebase数据库结构
登录Firebase控制台,导航到实时数据库的Users节点,确认每个子节点的结构:
- 正确结构应该是每个子节点(通常用用户ID作为键)下包含
name、email、phoneNumber等字段的对象,示例:Users |- user_123 |- name: "张三" |- email: "zhangsan@example.com" |- phoneNumber: "13800138000" |- ...其他User类定义的字段 - 如果发现某个子节点是直接的字符串(比如
Users下有个节点值为"test"),直接删除该异常节点。
2. 代码层面增加防御性处理
修改NewsfeedActivity中的onDataChange方法,增加类型检查,避免因异常数据崩溃:
override fun onDataChange(snapshot: DataSnapshot) { if (snapshot.exists()){ userArrayList.clear() // 避免重复加载数据 for (userSnapshot in snapshot.children){ // 先判断当前子节点是否为对象类型 if (userSnapshot.value is Map<*, *>) { val user = userSnapshot.getValue(User::class.java) user?.let { userArrayList.add(it) } } else { // 打印异常数据的节点键和值,方便定位问题 Log.e("UserDataError", "无效的用户数据节点:${userSnapshot.key},值为:${userSnapshot.value}") } } userRecyclerView.adapter = MyAdapter(userArrayList) userRecyclerView.adapter?.notifyDataSetChanged() } }
同时修改onCancelled方法,先打印错误日志再结束Activity,便于排查数据库权限或连接问题:
override fun onCancelled(error: DatabaseError) { Log.e("FirebaseError", "数据库访问被取消:${error.message},错误码:${error.code}") finish() }
3. 确认数据写入逻辑的正确性
检查写入Users节点的代码,确保每次写入的都是User对象,而非字符串:
正确的写入示例:
val newUser = User( name = "李四", email = "lisi@example.com", phoneNumber = "13900139000", bloodGroup = "B-", cityName = "上海", availabality = "可用" ) // 生成唯一用户ID作为子节点键 val userId = FirebaseDatabase.getInstance().getReference("Users").push().key ?: "" FirebaseDatabase.getInstance().getReference("Users").child(userId).setValue(newUser)
避免出现直接写入字符串的错误逻辑(如下代码会导致读取崩溃):
// 错误示例:直接写入字符串而非User对象 FirebaseDatabase.getInstance().getReference("Users").child("test").setValue("这是错误的字符串数据")
内容的提问来源于stack exchange,提问作者Abdur Rahman
相关产品推荐
相关产品推荐

