我正在尝试使用 Firebase 创建排行榜并显示用户名、高分、区域。

Posted

技术标签:

【中文标题】我正在尝试使用 Firebase 创建排行榜并显示用户名、高分、区域。【英文标题】:I'm trying to create a leaderboard using Firebase and show the username, highscore, region. 【发布时间】:2016-10-24 22:49:32 【问题描述】:

我的目标是使用 Firebase 创建一个排行榜,并在表格视图中显示用户名、高分和区域。我当前的数据库看起来像这样

我现在拥有所有用户。我这样做是为了增加当前用户的数据。不幸的是,通过这种方式,我认为我不能让别人看到别人的高分或用户名。 使用当前节点设置是否可以解决此问题,或者我是否需要更改它。如果是这样,有人可以举例说明数据库的外观。

【问题讨论】:

【参考方案1】:

您应该将您的用户特定数据与排行榜分开。

您有您的用户节点,其中您的用户数据位于其唯一用户 ID 下。 然后您还可以创建一个排行榜节点,并在相同的唯一用户 ID 下创建您的排行榜特定数据。这样一来,您就不必一次获取所有数据来了解用户特定的数据。

连接是用户 ID,即唯一 ID,您的用户将知道并通过该 ID 检索他/她的数据。其他玩家可以通过查询来检索排行榜节点。您还应该存储一些看似多余的数据,例如用户节点和排行榜都需要的用户名。

不要忘记应用安全规则,因此用户只能写入他/她的数据。

看起来像这样:

知道他/她的 UID 的经过身份验证的用户然后可以通过在此路径上获取数据来收听他/她自己的排行榜分数:“排行榜/UID”对。

其他玩家应该只需要使用路径:“排行榜”来获取排行榜上的每个玩家。要对它们进行排序并仅获取前 10 名玩家,您必须使用查询。

使用 queryOrderedByChild 按高分排序您的数据 为此,您还应该添加安全规则:“.indexOn”:“highscore”。

要获取前 10 名玩家,请使用 queryLimitedToFirst 设置为 10,只会下载排名前 10 的玩家。

您应该阅读有关查询的更多信息:https://firebase.google.com/docs/database/ios/lists-of-data#sorting_and_filtering_data

【讨论】:

一些事情。你能给我一个在 UID 之后查询所有内容的代码示例吗?因为即使这更有效,它也没有解决我遇到的问题。如果我没有对 UID 的引用,我不确定查询或显示快照。我知道如何为当前用户执行此操作,但是如何查看所有用户及其节点。 不能给你确切的代码,因为我不熟悉 swift 但添加了一些信息编辑的答案。 感谢您回答我的问题。 @Durian 这不对。如果您使用 rootRef.leaderboardRef.queryOrdered(byChild: score),您将如何查询“分数”。这不起作用,因为 score 不是排行榜的子项,如果您要采用这种方法,则需要遍历每个 userId。 如果 orderByChild 不是 Leaderboards 的子级,你还能怎么办。分数是排行榜的子项。这不是直接的孩子。【参考方案2】:

使用 JSON 时,树越扁平越好

HighScore :
  userID1 : 100,
  userID2 : 103;
  userID3 : 210;
   , 
Users :
  userID1 :...
  userID2 :...
  userID3 :...     
 

如果您想为用户添加不同的关系属性,只需为该特定用户添加另一个父节点并查询它。

FIRDatabase.database().reference().child("HighScores").observeSingleEvent(of: .value, with: (Snap) in

        print(Snap.value)

    )

PS:- 您可以随时使用 firebase 中的安全规则,将数据库中特定节点的权限操作给经过身份验证的用户Docs Link。

要将您的数据附加到 firebase 节点:-

 FIRDatabase.database().reference().child("HighScores").observeSingleEvent(of: .value, with: (Snap) in

        if let snapDict = Snap.value as? NSMutableDictionary

            snapDict.setObject(_yourHighScore, forKey : FIRAuth.auth()!.currentUser!.uid as NSCopying)
            FIRDatabase.database().reference().child("HighScores").setValue(snapDict)
        
    )

【讨论】:

但是如何添加更多玩家,因为 .set 只是删除其他玩家并添加最新玩家。【参考方案3】:

如果需要,您可以将所有内容存储在用户节点下。并通过应用基于高分的排序来获取用户详细信息。您还应该应用限制。

如果您计划为用户详细信息和分数创建单独的节点,那么您必须从分数节点获取分数并根据用户 ID 从用户节点获取用户详细信息。

【讨论】:

【参考方案4】:

加上@Durian 的回答,代码应该是这样的,

let leaderboardDB = Database.database().reference().child("leaderboards")
leaderboardDB.queryOrdered(byChild: "score").queryLimited(toFirst: 100).observeSingleEvent(of: DataEventType.value, with:  (snapshot) in
            if snapshot.exists() 
                print("Retrieving Data!")
                for child in snapshot.children 
                   print("Do whatever you need to do with the data")
                
             else 
                print("DB no data!")
            
        )
     

您可以将 queryOrder 方法调用与 queryLimited 方法链接在一起以检索数据。您不必为包装排行榜数据的 userId 烦恼,queryOrdered(byChild: "score") 方法将查看数据库中每个人的得分并相应地对其进行排序。

【讨论】:

以上是关于我正在尝试使用 Firebase 创建排行榜并显示用户名、高分、区域。的主要内容,如果未能解决你的问题,请参考以下文章

使用 swiftyJSON/swift 从 Firebase 解析排行榜数据

实时更新分数

Firebase生成的数据表无法稳定显示

将 Google Play 游戏与 Firebase 混合使用

尝试创建关卡排行榜时,Leaderboard.map 不是函数

Google Play 游戏、Firebase 和新的 Google 登录