Meteor.loginWithFacebook not storing email address

I'm using

On the server:

ServiceConfiguration.configurations.remove({
    service: 'facebook'
});

ServiceConfiguration.configurations.upsert(
    { service: 'facebook' },
    { $set: {
        appId: 'xxxxxxxxxxxxxxxx',
        secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
      }
    }
);

On the client:

Meteor.loginWithFacebook({requestPermissions: ['email']}, function(error){
  if (error) {
    throwError('Could not log in');
  } else {
    // success
  }
});

This configuration prompts the user for Facebook verification with access to email and returns no errors. A new user is stores with the correct name and ID. But this e-mail is not stored in the user object.

This is what I get when i fetch a user from the shell.

{ _id: 'xxxxxxxxxxxxxxxxx',
  createdAt: Mon Jul 13 2015 13:36:21 GMT+0200 (CEST),
  services: 
   { facebook: 
      { accessToken: 'xxxxxxxxxxxxxxxxxxxxx...',
        expiresAt: 1441971380621,
        id: 'xxxxxxxxxxxxxxxxx',
        name: 'xxxx xxxxxx' },
     resume: { loginTokens: [Object] } },
  profile: { name: 'xxxx xxxxxx' } }

Why is the email address from Facebook not being stored?

Answers:

Answer

While I have reported the issue to Meteor I've found a quick fix for the time being.

On the server run this:

Accounts.onCreateUser(function(options, user) {
  if (user.hasOwnProperty('services') && user.services.hasOwnProperty('facebook')  ) {
    var fb = user.services.facebook;
    var result = Meteor.http.get('https://graph.facebook.com/v2.4/' + fb.id + '?access_token=' + fb.accessToken + '&fields=name,email');

    if (!result.error) {
      _.extend(user, {
        "emails": [{"address": result.data.email, "verified": false}],
        "profile": {"name": result.data.name}
      });
    }
  }

  return user;
});

[EDIT]

The previous code works, but since it causes problems with other login methods I went with another approach:

In the client I call a function on the server when the user authenticates with Facebook:

Meteor.loginWithFacebook({requestPermissions: ['email']}, function(error){
  if (error) {
    //error
  } else {
    Meteor.call('fbAddEmail');
  }
});

And then on the server:

Meteor.startup(function () {
  Meteor.methods({
    fbAddEmail: function() {
      var user = Meteor.user();
      if (user.hasOwnProperty('services') && user.services.hasOwnProperty('facebook')  ) {
        var fb = user.services.facebook;
        var result = Meteor.http.get('https://graph.facebook.com/v2.4/' + fb.id + '?access_token=' + fb.accessToken + '&fields=name,email');

        if (!result.error) {
          Meteor.users.update({_id: user._id}, {
            $addToSet: { "emails": {
              'address': result.data.email,
              'verified': false
            }}
          });
        }
      }
    }
  });
});
Answer

Facebook API may not return the email address for some users even if you asked for the "email" permission. The official API docs state that:

[email] field will not be returned if no valid email address is available.

One of the reason may be an unconfirmed email address and another one a user who registered with a mobile phone number only.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.