Nedim Kurbegović Nedim Kurbegović - 3 years ago 87
iOS Question

Populate tableview with Facebook Friends

The idea is to fill an array of strings with IDs of Facebook Friends (from Graph request), then search the (Firebase) database for those IDs (as children) and, finally, populate the tableview with the relevant data (username, image) read from the database.
This is why I tried:

let params = ["fields": "id"]

let request = FBSDKGraphRequest(graphPath: "me/friends", parameters: params, httpMethod: "GET")
let connection = FBSDKGraphRequestConnection()
connection.add(request, completionHandler: { (connection, result, error) in
if error != nil {
print("error")
} else {
if let userData = result as? [String:Any] {
let data: NSArray = userData["data"] as! NSArray
for i in 0..<data.count {
let dict = data[i] as! NSDictionary
let temp = dict.value(forKey: "id") as! String
// temp is an ID of a Facebook friend
self.ref.child("users").queryOrdered(byChild: "fbid").queryEqual(toValue: temp).observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists() {
let snap = snapshot.value as? NSDictionary
self.usersArray.append(snap?["username"] as! String)
self.tableView.reloadData()
//tableview is obviously populated with usersAray
}
})

}
}
}
})
connection.start()


without luck. I hope there are better and faster ways to accomplish the goal. Thank you in advance.

Jay Jay
Answer Source

The code looks ok and appears to work so one modification would be to reload the tableView after the array is populated instead of each time through - that would prevent flicker. You'll have to do it asynchronously so the table update occurs after the loading of the data. It won't speed it up really but it's unclear from the question what part is 'slow'

Another option would be to load the /users node by .value into an array and look up the fbid via that array instead of hitting Firebase over and over. That solution may/may not be viable depending on the number of users.

A super cool option would be to have a separate node with just the Facebook id's and the user names. So if your users node looks like this

/users
   uid_0
     fbid: "fbid_1"
     name: "Pete"
   uid_1
     fbid: "fbid_2"
     name: "George"

have another node that provides direct access to the data you want instead of running a query.

/lookup
   fbid_1: "Pete"
   fbid_2: "George"

that would greatly simply your loading code - something like this

for i in  0..<data.count {
    let fbid = data[i]
    let userRef = self.ref.child("lookup").child(fbid)
    userRef.observeSingleEvent(of: .value, with: { snapshot in
        let name = snapshot.value as! String
        usersArray.append(name)
    })
}

Firebase queries are 'heavier' than directly accessing a node and if you are doing a lot of that directly loading the node and avoiding a query can speed up access.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download