The data browser is built for Chrome, Firefox, Safari, and IE9 and above. Please upgrade your browser, or download Google Chrome to get the best experience.
Back to Questions

How can I find Parse Users that are Facebook friends with the current user?

40 votes     1 answer     48.9k views     

40

1 Answer

57

Parse Users' Facebook ids are private (and thus cannot be used in a query) by default, and it is up to you as a developer to decide whether this data should be visible to other users of your application.

To accomplish this, you can use the Facebook API to get the user's Facebook ID, assign it to a field on the Parse User. Then you can construct a query on the User collection to get a list of Parse users whose Facebook IDs are in your user's friend list.

In iOS, your code to make your users query-able by Facebook ID would look like this:

// When your user logs in, immediately get and store its Facebook ID
[PFFacebookUtils logInWithPermissions:permissionsArray
                                block:^(PFUser *user, NSError *error) {
  if (user) {
    [FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
      if (!error) {
        // Store the current user's Facebook ID on the user
        [[PFUser currentUser] setObject:[result objectForKey:@"id"]
                                 forKey:@"fbId"];
        [[PFUser currentUser] saveInBackground];
      }
    }];
  }
}];

Then, when you are ready to search for your user's friends, you would issue another request:

// Issue a Facebook Graph API request to get your user's friend list
[FBRequestConnection startForMyFriendsWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
  if (!error) {
    // result will contain an array with your user's friends in the "data" key
    NSArray *friendObjects = [result objectForKey:@"data"];
    NSMutableArray *friendIds = [NSMutableArray arrayWithCapacity:friendObjects.count];
    // Create a list of friends' Facebook IDs
    for (NSDictionary *friendObject in friendObjects) {
        [friendIds addObject:[friendObject objectForKey:@"id"]];
    }

    // Construct a PFUser query that will find friends whose facebook ids
    // are contained in the current user's friend list.
    PFQuery *friendQuery = [PFUser query];
    [friendQuery whereKey:@"fbId" containedIn:friendIds];

    // findObjects will return a list of PFUsers that are friends
    // with the current user
    NSArray *friendUsers = [friendQuery findObjects];
  }
}];

For Android, your code to make your users query-able by Facebook ID would look like this:

ParseFacebookUtils.logIn(this, new LogInCallback() {
  @Override
  public void done(ParseUser user, ParseException error) {
    // When your user logs in, immediately get and store its Facebook ID
    if (user != null) {
      getFacebookIdInBackground();
    }
  }
});

private static void getFacebookIdInBackground() {
  Request.executeMeRequestAsync(ParseFacebookUtils.getSession(), new Request.GraphUserCallback() {
    @Override
    public void onCompleted(GraphUser user, Response response) {
      if (user != null) {
        ParseUser.getCurrentUser().put("fbId", user.getId());
        ParseUser.getCurrentUser().saveInBackground();
      }
    }
  });
}

Then, when you are ready to search for your user's friends, you would issue another request:

Request.executeMyFriendsRequestAsync(ParseFacebookUtils.getSession(), new Request.GraphUserListCallback() {

  @Override
  public void onCompleted(List<GraphUser> users, Response response) {
    if (users != null) {
      List<String> friendsList = new ArrayList<String>();
      for (GraphUser user : users) {
        friendsList.add(user.getId());
      }

      // Construct a ParseUser query that will find friends whose
      // facebook IDs are contained in the current user's friend list.
      ParseQuery friendQuery = ParseQuery.getUserQuery();
      friendQuery.whereContainedIn("fbId", friendsList);

      // findObjects will return a list of ParseUsers that are friends with
      // the current user
      List<ParseObject> friendUsers = friendQuery.find();
    }
  }
});

Updated answer with new Facebook SDK 3.0 methods.

- Héctor Ramos over 1 year ago

Thanks, And sorry I posted my question as "answer", did not notice this is a Question -> answer area. Cant find how to delete it. Can you clean that up? :)

- Andres Canella over 1 year ago

Also, for some applications you can get away with doing this: [PF_FBRequest requestWithGraphPath:@"me/friends" parameters:@{@"fields":@"id,name,installed"} HTTPMethod:@"GET"]; I prefer this because then I see if they have the app or not installed.

- Brandon Copley over 1 year ago

Now that we can run server logic using Cloud Code, what would be the ideal way to do this more efficiently?

- Andres Canella over 1 year ago

It doesn't appear that the server has access to our facebook access tokens - so this can't be done server side.

- Brandon Copley over 1 year ago

Thanks Brandon.

- Andres Canella over 1 year ago

I should do some testing to confirm though... I have not tested.

- Brandon Copley over 1 year ago

That would be great, let me know if you do. I havent played around with Cloud Code myself but will be needing some back end logic for our next app.

- Andres Canella over 1 year ago

Im using it already to greatly speed up app interactions, so far it's been fantastic.

- Brandon Copley over 1 year ago

hi! is there a way to do a graph query with the Javascript SDK?

- Viddsee over 1 year ago

Weird, im getting an empity array on NSArray *friendUsers = [friendQuery findObjects];, but the friendIds count is correct....

- Vinicius over 1 year ago

Vinicius and Viddsee, if you still need help with these, can you please add these as new Questions?

- Héctor Ramos over 1 year ago

How to revalidate session in case we are getting "message = "An active access token must be used to query information about the current user." or a OAuthException ;

- Rapidsoft over 1 year ago

Ashu, can you please add this as a new question?

- Héctor Ramos over 1 year ago

This doesn't seem to be updated for Android, as getFacebook() is deprecated.

- Charles Lee about 1 year ago

Like Vinicius, I'm getting an empty array. Question asked by ashu sharma is still unanswered. How to revalidate session if "An active access token must be used to query information about the current user"

- Fernando about 1 year ago

Please add these as separate questions, as the comment thread is not a good place to answer different questions.

- Héctor Ramos about 1 year ago

https://parse.com/questions/how-to-activate-facebook-session

- Fernando about 1 year ago

When updating to Parse's latest version ashu sharma's problem was resolved. But I still get an empty array of friends when following this tutorial. Get a list of friendIds, but an empty array of friends after querying. (iOS)

- Fernando about 1 year ago

The Facebook Graph API request will get you a list of ids which correspond to your Facebook friend's Facebook IDs. It will then query for PFUsers in your Parse app which have a matching Facebook ID. If you don't have any common Facebook friends in your PFUser table, this query will return an empty set. You can try setting it up with some sample data based on your existing Facebook friends.

- Héctor Ramos about 1 year ago

i do have a facebook friend who's in my Parse User table

- Fernando about 1 year ago

found the problem, my friend used an older version of the app, which didn't set the fbId field

- Fernando about 1 year ago

yep, works fine now! thanks Héctor

- Fernando about 1 year ago

According to the Parse documentation, "ParseFacebookUtiols.getFacebook()" is deprecated. Is there another way of doing this which is completely updated to the Facebook SDK 3.0?

- Thom about 1 year ago

Updated my Android example to use the new Facebook 3.0 SDK as documented in the Facebook API Reference: https://developers.facebook.com/docs/reference/android/3.0/Request

- Héctor Ramos about 1 year ago

Thanks, Hector, that's perfect.

- Thom about 1 year ago

Hector for presidente!

- Duncan Campbell about 1 year ago