8

I'm trying to allow users that have connected their Facebook accounts to my rails app to find their Facebook friends that have already registered in the app, preferably in an index like format (similar to Formspring's display).

Currently I'm using Devise, OAuth+Fbook Javascript SDK, and Koala. I have the Facebook UID of each user that connects their Facebook saved in the db, but I don't know how to filter through the results of the Facebook API call @friends = @graph.get_connections("me", "friends") in order to display the users that have matching UID's to the API call data.

Any thoughts? There's probably an even better way, so lemme know if any additional info is needed. Thanks very much for your help!

EDIT (screenshot of index action in users controller)

enter image description here

Note in @oauth, app id and app secret are cropped out in the example image

ahuang7
  • 804
  • 1
  • 11
  • 26

2 Answers2

16

If you can get an array of UID's for the user's friends, you can find them all in a single SQL statement using IN (some handwaving and/or pseudocode here, depending on attributes, etc):

uids = @friends.collect(&:uid)
# uids is an array of Facebook UID's, say [1234, 5678, 9012]
registered_friends = User.where('fb_uid IN (?)', uids)
# "SELECT users.* FROM users WHERE (fb_uid IN (1234, 5678, 9012))"

If your Facebook data is in another model, you can select off that model and do an includes to bring in the user.

registered_friends = Authorizations.where(:type => 'Facebook') \
  .where('fb_uid IN (?)', uids).includes(:user).collect(&:user)

[Update]

Looks like Koala returns an array of string-based Hashes, so you won't be able to use collect(&:id) to get the IDs. Here's what I used to get the array of IDs on the console (sensitive data masked, obviously):

pry(main)> oauth = Koala::Facebook::OAuth.new 'xxxxxxx', 'yyyyyyyyy'
=> #<Koala::Facebook::OAuth:0x00000100d03be8>
pry(main)> token = 'zzzzzzzzzz'
=> "zzzzzzzzzz"
pry(main)> graph = Koala::Facebook::GraphAPI.new token
=> #<Koala::Facebook::GraphAPI:0x00000100ce3ac8>
pry(main)> friends = graph.get_connections "me", "friends"
=> [{"name"=>"A Friend", "id"=>"An ID"}, {"name"=>"Another Friend", "id"=>"Another ID"}]
uids = friends.collect { |f| f["id"] }
=> ["An ID", "Another ID"]

Also, if you're following Rails conventions, the id field of your Services table is going to be the primary key of the record, and not the Facebook ID of the service user, so you may need to query on another field.

Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
  • I've attempted to implement your answer (see screenshot above), but when I call @uids in the users/index view (which im doing to see if it gets the right info), the numbers displayed are not the Facebook ids of the users from the graph api call. I get one number shown "21565518202156551420" that is unrelated. Is there anything I'm doing incorrectly? I appreciate your wisdom! – ahuang7 Apr 28 '11 at 03:30
  • I've updated my answer after messing with Koala; see if you have any more luck with that! – Michelle Tilley Apr 28 '11 at 14:58
  • Wow that's awesome, you are a coding god. Thanks again! – ahuang7 Apr 28 '11 at 19:01
  • 1
    Hardly, but thanks for the compliment! Glad I was able to help. – Michelle Tilley Apr 28 '11 at 20:20
  • Is there a simple way to find out if a user is friends with another specific user? I'd rather not wait for FB to return all of a user's friends if I'm only interested in checking one as this could be a large amount of data and take a while. – Aaron Jan 19 '12 at 16:42
2

[Update]

Facebook's Graph API no longer gives access to the full user's friend list for version >= 2.0.
From the API's documentation:

App Friends: The /me/friends endpoint no longer includes the full list of a person's friends. Instead, it now returns the list of that person's friends who are also using your app.

Andre
  • 63
  • 6