我的应用程序有一个最高得分表,该表使用.queryOrdered(byChild:“ userHighScore”)和.queryLimited(toLast:100)来获得最高100分:
func getTopScores() {
var scores = [String]()
self.reference
.child("users")
.queryOrdered(byChild: "userHighScore")
.queryLimited(toLast: 100)
.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children.reversed() {
if let dataSnapshot = child as? DataSnapshot, let user = dataSnapshot.value as? [String:AnyObject] {
if let userHighScore = user["userHighScore"] as? Int {
var stringToAppend = "\(scores.count+1). "
if let userName = user["userName"] as? String {
stringToAppend += " \(userName) • \(userHighScore)"
}
scores.append(stringToAppend)
}
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
问题是当有平局得分时。
理想情况下,第一个获得该分数的用户应高于表中具有相同分数的其他用户(而获得该分数的最新用户将是拥有相同分数的用户中最低的)。
但是,该表以与Firebase实时数据库中出现的相同的随机顺序显示得分相同的得分。
有没有办法按时间顺序排序并列分数?
我已经为此花了好几个小时。在此先感谢您的帮助!
理想情况下,第一个获得该分数的用户应高于其他具有相同分数的用户
您实际上是在尝试对两个属性进行排序:userHighScore和userHighScoreTimestamp(由于您没有在问题中指定它,所以我起了一个名字)。Firebase实时数据库只能查询单个属性。请参阅基于Firebase中的多个where子句进行查询
您可以做的是定义一个附加属性,该属性结合了高分值和已完成的时间戳:
users: {
derenceUid: {
userHighScore: 42,
userHighScoreTimestamp: 1557695609344,
userHighScore_Timestamp: "000042_1557695609344",
},
dougUid: {
userHighScore: 31,
userHighScoreTimestamp: 1557609264895,
userHighScore_Timestamp: "000005_1557609264895",
},
pufUid: {
userHighScore: 42,
userHighScoreTimestamp: 1557695651730,
userHighScore_Timestamp: "000042_1557695651730",
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种结构,您可以通过以下方式获得最近得分最高的用户:
ref.queryOrdered(byChild: "userHighScore_Timestamp"). queryLimited(toLast: 1)
Run Code Online (Sandbox Code Playgroud)
需要注意的一件事是,我将用户的高分填充为六位数。这是必要的,因为Firebase将对这些键进行字典比较,并且如果没有填充,填充"5_1557609264895"将大于"42_1557695609344"。您必须弄清楚最高分数可以保留几位数。在我的示例中,我使用6位数字,因此它最多可以保存100万个分数。
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |