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

如何按降序查询Firebase Score集合高分并在TextMeshPro展示

搞定Firebase分数排序展示到TextMeshPro的问题

先查最容易踩的坑

首先确认你Firebase里Score集合的分数字段(比如叫score)是纯数值类型,要是存成字符串,排序会按字典序来(比如"100"会排在"99"前面),这绝对是高频翻车点。

修复后的完整代码

假设你的分数字段叫score,下面是能正常跑的代码:

using UnityEngine;
using TMPro;
using Firebase.Firestore;
using System.Collections.Generic;

public class ScoreDisplay : MonoBehaviour
{
    public TextMeshProUGUI scoreText;
    private FirebaseFirestore db;

    void Start()
    {
        db = FirebaseFirestore.DefaultInstance;
        FetchAndDisplayScores();
    }

    void FetchAndDisplayScores()
    {
        // 构建查询:按score降序排,这里限制只取前10条高分,可按需调整
        Query scoreQuery = db.Collection("Score")
                             .OrderByDescending("score")
                             .Limit(10);

        // 异步拿数据
        scoreQuery.GetSnapshotAsync().ContinueWith(task =>
        {
            if (task.IsFaulted)
            {
                Debug.LogError("拿分数失败: " + task.Exception);
                return;
            }

            QuerySnapshot snapshot = task.Result;
            string scoreDisplayText = "高分榜:\n";

            // 遍历结果拼文本
            foreach (DocumentSnapshot doc in snapshot.Documents)
            {
                Dictionary<string, object> scoreData = doc.ToDictionary();
                // 先检查字段存不存在,而且得是数值类型
                if (scoreData.ContainsKey("score") && scoreData["score"] is long scoreValue)
                {
                    string playerName = scoreData.ContainsKey("playerName") ? scoreData["playerName"].ToString() : "匿名玩家";
                    scoreDisplayText += $"{playerName}: {scoreValue}\n";
                }
            }

            // 必须切回主线程更UI!Firebase回调在子线程,直接改会崩
            UnityMainThreadDispatcher.Instance().Enqueue(() =>
            {
                scoreText.text = scoreDisplayText;
            });
        });
    }
}

关键修复点

  • 排序逻辑要对:用OrderByDescending("score")才是从高到低排,注意字段名要和Firebase里的完全一致(大小写敏感!别写错)。
  • 主线程更UI:Firebase的回调是在子线程跑的,直接改TextMeshPro会没反应甚至报错,必须用主线程调度器。如果你的项目里没有这个调度器,自己加个简单的:
using UnityEngine;
using System.Collections.Generic;

public class UnityMainThreadDispatcher : MonoBehaviour
{
    private static UnityMainThreadDispatcher _instance;
    private Queue<System.Action> _actions = new Queue<System.Action>();

    public static UnityMainThreadDispatcher Instance()
    {
        if (_instance == null)
        {
            _instance = FindObjectOfType<UnityMainThreadDispatcher>();
            if (_instance == null)
            {
                GameObject obj = new GameObject("MainThreadDispatcher");
                _instance = obj.AddComponent<UnityMainThreadDispatcher>();
                DontDestroyOnLoad(obj);
            }
        }
        return _instance;
    }

    void Update()
    {
        lock (_actions)
        {
            while (_actions.Count > 0)
            {
                _actions.Dequeue().Invoke();
            }
        }
    }

    public void Enqueue(System.Action action)
    {
        lock (_actions)
        {
            _actions.Enqueue(action);
        }
    }
}
  • 数据类型要对:从Firebase读出来的分数得是数值(long或int),要是之前存的是字符串,赶紧去Firebase控制台改成数值类型再测试。

额外要注意的

  • 检查Firebase的安全规则,确保Score集合能被读取,不然查询直接被拒:

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Score/{document} {
allow read, write: if true; // 测试用,上线记得改成正经权限控制
}
}
}

  • 测试的时候可以在Firebase控制台手动加几条不同分数的数据,看看排序对不对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:30:28