45

I'm upgrading my app to Facebook-iOS-SDK-4.0, but seems like I can't get user email from FBSDKProfile, since it only provide, username, userid, etc.

Janmenjaya
  • 4,149
  • 1
  • 23
  • 43
imcc
  • 879
  • 2
  • 10
  • 15
  • I have tried the same code as in your accepted answer however I am not getting email id though I have 'email' permission. I am getting only user id and username in result parameter. – ViruMax Jul 13 '15 at 11:19
  • 3
    **Issue resolved in duplicate post:** http://stackoverflow.com/a/31503463/3382676 – HeTzi Jul 19 '15 at 16:57
  • I have not yet tried it, but it seems legit. Thanks @HeTzi – imcc Jul 20 '15 at 20:19

8 Answers8

129

To fetch email you need to utilize the graph API, specifically providing the parameters field populated with the fields you want. Take a look at Facebook's Graph API explore tool, which can help to figure out the queries. https://developers.facebook.com/tools/explorer

The code that worked for me to fetch email is the following, which assumes you are already logged in:

    NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
    [parameters setValue:@"id,name,email" forKey:@"fields"];

    [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters]
     startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
                                  id result, NSError *error) {
         aHandler(result, error);
     }];
genericdan
  • 1,321
  • 2
  • 9
  • 3
28

That's correct. The email address is not present in the FBSDKProfile object. You should use FB's Graph API instead. There is plenty of info and code samples at the FB Developer site https://developers.facebook.com/docs/ios/graph

To answer your question, try something like this.

if ([FBSDKAccessToken currentAccessToken]) {
   [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"email"}]
    startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
      if (!error) {
         NSLog(@"user:%@", result);       
      }
  }];
}
codrut
  • 810
  • 10
  • 19
franciscodlp
  • 537
  • 4
  • 8
  • 4
    that's what I'm doing right now, but it is waste of resource. – imcc Mar 29 '15 at 23:17
  • 12
    This request does not have email in the result. – Alexander Volkov Apr 11 '15 at 06:02
  • 4
    I tried to login like this: fbLoginManager.logInWithReadPermissions(["email", "public_profile"] ... and the email is still not sent in the result object. Anyone knows how to do it? – Bence Pattogato Apr 12 '15 at 13:55
  • @BencePattogato you can up vote this ticket for more people to see it. – imcc Apr 14 '15 at 20:29
  • 1
    @BencePattogato We'd need further details to help you out. I just tried the code I posted using the permissions ["public_profile", "email", "user_friends"] and I'm receiving the user's email in the results. You may want to check FBSDKAccessToken properties (declinedPermissions, permissions) to make sure you actually have the required permission. – franciscodlp Apr 14 '15 at 23:11
  • @BencePattogato That's correct. You should declare "email" in requested permissions and later you'll get email within FBSDKGraphRequest result – mkll Apr 24 '15 at 19:56
  • I believe fb should have given it in profile directly – Aqib Mumtaz Apr 27 '15 at 13:01
  • I have tried the same code however I am not getting email id though I have 'email' permission. I am getting only user id and username in result parameter. – ViruMax Jul 13 '15 at 11:18
  • 14
    with nil parameters you'll get only userId and name, for email-id send ["fields":"email"] in parameters – Gaurav Rana Jul 14 '15 at 12:49
  • 2
    **Issue resolved in duplicate post:** http://stackoverflow.com/a/31503463/3382676 – HeTzi Jul 19 '15 at 16:57
  • Actually I have found the solution. For latest Graph api version we need to pass parameters in graphpath ie. @"me/emailId?location" explicitly. It was not mentioned in their documentation. – ViruMax Oct 01 '15 at 06:32
  • u saved my life @GauravRana – dondonhk Oct 04 '15 at 08:04
  • @GauravRana I tried looking in Facebook doc ref for parameter names, unable to find any.... Do you have a link to a parameter list? – DevilInDisguise Oct 14 '15 at 11:23
  • Please note that in recent versions of Facebook SDK you require to specify parameters. Otherwise you will receive a warning like this: FBSDKLog: starting with Graph API v2.4, GET requests for /me should contain an explicit "fields" parameter – Julio Bailon Oct 21 '15 at 14:04
6

Code corrected:

  if ([FBSDKAccessToken currentAccessToken]) {
    [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:nil]
        startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
                                     id result, NSError *error) {
          if (!error) {
            NSLog(@"fetched user:%@", result);
          }
        }];
  }
Aqib Mumtaz
  • 4,936
  • 1
  • 36
  • 33
  • I have tried the same code however I am not getting email id though I have 'email' permission. I am getting only user id and username in result parameter. – ViruMax Jul 13 '15 at 11:18
  • 1
    sorry for late reply, make sure your email address is verified for facebook account, if not then you may need to resend varification email from your facebook account and click on email verification link – Aqib Mumtaz Oct 01 '15 at 01:26
  • 1
    Actually I have found the solution. For latest Graph api version we need to pass parameters in graphpath ie. @"me/emailId?location" explicitly. It was not mentioned in their documentation. – ViruMax Oct 01 '15 at 06:27
5

Try this code :

FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:@[@"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
    if (error) {
        // Process error
    } else if (result.isCancelled) {
        // Handle cancellations
    } else {
        // If you ask for multiple permissions at once, you
        // should check if specific permissions missing

        if ([result.grantedPermissions containsObject:@"email"]) {
            if ([FBSDKAccessToken currentAccessToken]) {
                [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:nil]
                 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
                     if (!error) {
                         NSLog(@"fetched user:%@", result);
                     }
                 }];
            }
        }
    }
}];
Dhaval H. Nena
  • 3,992
  • 1
  • 37
  • 50
  • 5
    I have tried the same code however I am not getting email id though I have 'email' permission. I am getting only user id and username in result parameter. – ViruMax Jul 13 '15 at 11:18
  • Make sure your email has been verified by clicking on the link sent by facebook, this may also cause issue. – Aqib Mumtaz Jul 13 '15 at 13:38
3

These parameters gives the email

NSDictionary *parameters = @{@"fields":@"email"};

[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters]
 startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) 
{
    NSLog(@"fetched user:%@", result);
}];

starting with Graph API v2.4, GET requests for /me should contain an explicit "fields" parameter

Ted
  • 22,696
  • 11
  • 95
  • 109
2

From facebook developer site https://developers.facebook.com/docs/facebook-login/permissions/v2.2

Note, even if you request the email permission it is not guaranteed you will get an email address. For example, if someone signed up for Facebook with a phone number instead of an email address, the email field may be empty.

Hope it will help someone:)

DaNLtR
  • 561
  • 5
  • 21
1

I wanted to add on to this with what I found. For my FBSDKGraphRequest I was trying to pass in the permissions I was requesting at login as the fields. So I was setting fields as something like:

"email,user_location"

However, permissions and fields are different. For reference, these are fields: https://developers.facebook.com/docs/graph-api/reference/v2.4/user

So based on that link you want to pass:

"email,location"

Hope that helps someone!

tvalent2
  • 4,959
  • 10
  • 45
  • 87
0
if ([FBSDKAccessToken currentAccessToken]) {
   [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"email"}]
    startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
      if (!error) {
                    }
  }];
}                    
Md.Sukel Ali
  • 2,987
  • 5
  • 22
  • 34