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

从Firebase DataSnapshot提取数据失败,求解决建议

问题

已成功从Firebase Realtime Database获取DataSnapshot,但无法从中提取玩家列表数据。相关信息如下:

Firebase数据结构

{
"81MUB": [
    {
      "name": "Alejandro",
      "points": 0
    }
  ]
}

Player数据类

data class Player(
    val name: String,
    val points: Int
)

ViewModel代码

fun getCode(): String {
    val index = ('A'..'Z') + ('1'..'9')

    var code = ""

    for (i in 0..4){
        code += index[Random().nextInt(index.size)]
    }

    return code
}

class MviewModel : ViewModel() {
    private val _Players: MutableLiveData<MutableList<Player>> =
        MutableLiveData(mutableListOf<Player>(Player("Alejandro", 0)))
    private var _LobbyCode: String = ""
    private val dataBase = FirebaseDatabase.getInstance()

    fun getPlayer(): MutableLiveData<MutableList<Player>> = _Players

    fun createLobby() {
        _LobbyCode = getCode()
    }

    fun listener() {
        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                // 未实现数据提取逻辑
            }

            override fun onCancelled(databaseError: DatabaseError) {
                // 错误处理未完善
            }
        }

        dataBase.reference.child(_LobbyCode).addValueEventListener(postListener)
    }
}
解决方法

1. 调整Player数据类以支持Firebase反序列化

Firebase需要类提供无参构造函数才能完成数据反序列化,修改Player类:

data class Player(
    val name: String = "",
    val points: Int = 0
)

如果需要保留必填参数,可使用@JvmOverloads生成重载构造:

data class Player @JvmOverloads constructor(
    val name: String,
    val points: Int = 0
)

2. 实现onDataChange中的数据提取

在onDataChange方法中遍历DataSnapshot的子节点,转换为Player对象并更新LiveData:

override fun onDataChange(dataSnapshot: DataSnapshot) {
    val players = mutableListOf<Player>()
    // 遍历列表中的每个玩家节点
    for (child in dataSnapshot.children) {
        val player = child.getValue(Player::class.java)
        player?.let(players::add)
    }
    // 更新LiveData,触发UI更新
    _Players.value = players
}

3. 完善错误处理与前置检查

  • 在onCancelled中添加日志,便于排查问题:
    override fun onCancelled(databaseError: DatabaseError) {
        Log.e("MviewModel", "获取玩家数据失败", databaseError.toException())
    }
    
  • 确保调用listener()前已执行createLobby(),避免监听空路径导致无数据返回。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:50:45