Reputation: 537
My goal is to create a leaderboard using Firebase and to show the username, high score and region in a tableview. My current Database looks like this
I have everything under user at the moment. I did it this way so i could increment data for the current user. Unfortunately, by doing it this way, I don't think I can let others see someone elses high score or username. Is there a solution to this problem using the current node setup, or do I need to change it. And if so can someone give my examples of how the database should look.
Upvotes: 2
Views: 14059
Reputation: 11
You can store everything under user node if you want. And fetch user details by applying sort based on high score. You should also apply limit.
If you are planning to create separate node for user details and score then you must fetch score from the score node and based on user id fetch user detail from user node.
Upvotes: 1
Reputation: 624
Adding on to @Durian 's answer, the code should look something like this,
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!")
}
})
}
You can chain the queryOrder method call with queryLimited method together to retrieve the data. You don't have to be bothered with the userId wrapping your leaderboard datum, the queryOrdered(byChild: "score")
method will look through everyone's score in the database and order them accordingly.
Upvotes: 0
Reputation: 9945
While using JSON the flatter the tree the better it is to
HighScore :{
userID1 : 100,
userID2 : 103;
userID3 : 210;
},
Users :{
userID1 :{...}
userID2 :{...}
userID3 :{...}
}
If you want to add a different relational property to the user, just add another parent node for that particular user and query it.
FIRDatabase.database().reference().child("HighScores").observeSingleEvent(of: .value, with: {(Snap) in
print(Snap.value)
})
PS:- You can always play with security rules in firebase , to manipulate the permissions for specific node in the Database to your authenticated users Docs Link.
To append your data in firebase node:-
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)
}
})
Upvotes: 3
Reputation: 283
You should separate your user specific data from the leaderboards.
You have your users node in which your user's data under their unique user id. Then you also can create a leaderboards node and under the same unique user id, your leaderboard specific data. This way you won't have to fetch all the data at once only to know the user specific data.
The connection is the user id, that is the unique id, that your user is going to know, and retrieve his/her data by. The other players can just retrieve the leaderboards node by a query. You should also store some seemingly redundant data, for instance the username which you would both need for the user's node and for the leaderboards.
Don't forget to apply security rules, so the user can only write to his/her data.
Looking like this:
The authenticated user who knows his/her UID can then listen to his/her own leaderboard score by fetching data on this path: "leaderboards/UID" right.
Other players should just have to use the path: "leaderboards" to fetch every player on the leaderboard. To order them and only fetch the top 10 players you have to use queries.
Use queryOrderedByChild to order your data by highscore For this you should also add the security rule: ".indexOn": "highscore".
To fetch the top10 players use queryLimitedToFirst setting it to 10, it will only download the top 10 players.
You should read more about queries: https://firebase.google.com/docs/database/ios/lists-of-data#sorting_and_filtering_data
Upvotes: 7