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

安卓Kotlin+Firebase游戏:如何设计关联用户名的排行榜系统?

解决方案:Firestore排行榜用户名与分数关联展示

1. 先确认Firestore数据结构

确保你的数据结构能让单条文档同时包含用户名和对应难度的分数,两种可行结构示例:

结构1(按玩家存储多难度分数):
players (集合)

  • 玩家ID文档
    • username: "张三"
    • simpleScore: 120
    • mediumScore: 80
    • hardScore: 50

结构2(按难度拆分集合):
topSimple (集合)

  • 自动生成ID文档
    • username: "李四"
    • score: 150
      topMedium (集合)
  • ...
    topHard (集合)
  • ...

如果你的用户名和分数是分开存储在不同集合/文档的,先调整结构,保证要展示的字段在同一个文档内。

2. 定义强类型数据模型

放弃HashMap,用Kotlin数据类封装数据,避免键名错误和类型不安全问题:

data class PlayerScore(
    val username: String = "",
    val score: Int = 0
)

3. 修改Firestore查询逻辑

以简单难度为例,查询时直接读取包含用户名和分数的文档,排序后转成PlayerScore列表:

// TopPlayersActivity中查询简单难度数据的代码
val db = FirebaseFirestore.getInstance()
db.collection("topSimple") // 对应你的数据集合,结构1则用"players"
    .orderBy("score", Query.Direction.DESCENDING) // 结构1则用"simpleScore"
    .limit(10) // 可选:只取前10名
    .get()
    .addOnSuccessListener { documents ->
        val playerList = mutableListOf<PlayerScore>()
        for (doc in documents) {
            val username = doc.getString("username") ?: "匿名玩家"
            val score = doc.getLong("score")?.toInt() ?: 0 // 结构1则用"simpleScore"
            playerList.add(PlayerScore(username, score))
        }
        // 给RecyclerView绑定适配器
        val adapter = TopEasyPlayersAdapter(playerList)
        binding.rvTopSimple.adapter = adapter
    }
    .addOnFailureListener {
        // 处理查询失败逻辑,比如Toast提示
    }

4. 调整适配器代码

让TopEasyPlayersAdapter接收PlayerScore列表,在绑定视图时同时展示用户名和分数:

class TopEasyPlayersAdapter(private val playerScores: List<PlayerScore>) :
    RecyclerView.Adapter<TopEasyPlayersAdapter.ViewHolder>() {

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tvUsername: TextView = itemView.findViewById(R.id.tv_username)
        val tvScore: TextView = itemView.findViewById(R.id.tv_score)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_top_player, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val player = playerScores[position]
        holder.tvUsername.text = player.username
        holder.tvScore.text = player.score.toString()
    }

    override fun getItemCount(): Int = playerScores.size
}

5. 常见问题排查

  • 检查Firestore字段名和代码中的一致性(大小写敏感,比如username和userName是两个不同字段)
  • 确认玩家上传数据时,同时将用户名和对应难度分数写入同一个文档
  • 如果用匿名登录,要确保用户设置用户名后,同步更新对应的分数文档

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:27:38