0

I'm new with swift langage and I'm trying to code a function which permits to get the 6 most popular people on my Firebase Database.

I wrote an observer which place users in an array like that:

[[userID: numberOfFollowers], [userID: numberOfFollowers], ...]

I would like to keep only the 6 users with the highest number of followers.

Do you know if it is possible?

var people = [[String: Int]]()

func loadPeople() {
  var REF_FOLLOWERS = Database.database().reference().child("followers")

  REF_FOLLOWERS.observe(.value, with: { (snapshot: DataSnapshot!) in
     print("Got snapshot")
     if let dict = snapshot.value as? [String: Any] {
        for (key, value) in dict {
           var count = 1
           if let array = value as? [String: Any] {
              for _ in array {
                 count += 1
              }
           }

           self.people.append([key : count])
           self.tableView.reloadData()
        }
     }
  })
}
1
  • That's a database. Why don't you sort the items while fetching? Commented Feb 8, 2018 at 16:45

2 Answers 2

3

You could use something like:

var REF_FOLLOWERS = Database.database().reference().child("followers").queryOrdered(byChild: "numberOfFollowers").queryLimited(toFirst: 6).observe(.value, with: { (snapshot: DataSnapshot!) in {
}

This would give top 6 with the highest number of followers.

Sign up to request clarification or add additional context in comments.

3 Comments

This seems like the best solution. Why ask the database for ALL followers, then sort them every time they change. The database has query ordering and limiting built in, so why not use it? (voted)
The only thing you'll have to change is to get only the last 6, since sorting is always ascending in Firebase: queryLimited(toLast: 6). Btw that also means that you'll have to reverse the items on the client, typically by adding each subsequent one to the start of the view (instead of adding to the end).
My problem is that I don't have a value "numberOfFollowers" in my DataBase. Should I create a new child in order to increment a counter for each user ?
0
REF_FOLLOWERS.observe(.value, with: { (snapshot: DataSnapshot!) in
   print("Got snapshot")
   if let dict = snapshot.value as? [String: Any] {
      for (key, value) in dict {
         var count = 1
         if let array = value as? [String: Any] {
            for _ in array {
               count += 1
            }
         }

         self.people.append([key : count])
      }
   }
   // this line will sort them and return first 6
   self.people = self.people.sorted(by: { $0["numberOfFollowers"] ?? 0 > $1["numberOfFollowers"] ?? 0}).prefix(6)
   // reload data just once at the end - be efficient!
   self.tableView.reloadData()
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.