Peter Roehlen
Peter Roehlen

Reputation: 128

How can I create a method for retrieving user email address that is available on the client and server?

I've got facebook, google and regular registration/login turned on on my website. The problem I have is that the email address is stored in different fields depending on how the user first joined.

For regular users, it is in field emails[0].address. For facebook and google authenticated users it is in field services[0].email.

At various places in the client (templates, events) and on the server (method), I just want to call one method that works out which field to use and returns the email address. I also want to do something similar for the verification field.

I'm fairly new to meteor and the only ways I've found to do the above so far is to repeat the same logic in the client and on the server which doesn't sit well with me.

Upvotes: 0

Views: 111

Answers (1)

Tarang
Tarang

Reputation: 75975

The best thing to do would be to transfer the email address to 'emails' if they log in with facebook, google or another services for the first time. This would also make it more future proof incase you add other services, since meteor will always use emails.address (including in other packages)

Server side code:

Accounts.onCreateUser(function(user) {

    user.emails = user.emails || []; //If its null set it to an empty array

    if(user.services.facebook) {
        user.emails.push({address: user.services.facebook.email, verified: false});
    }else if(user.services.google) {
        user.emails.push({address: user.services.google.email, verified: false});
    }

    return user;

});

Then you can just check Meteor.user().emails[0].address every time.

Note: If not published due to the autopublish package you may have to publish the emails field for it to work on the client.

You may also have to run this the first time for users who have already logged in before:

Meteor.startup(function() {
    Meteor.users({'emails':{$exists: false}}).fetch().forEach(function(user) {
        var email = (user.services.facebook || user.services.google).email;

        if(email) Meteor.users.update({_id: user._id},{$push:{emails:{address: email, verified: false}}});
    });
});

I'm not sure if facebook and google both use email in the services key, if they do the above should work fine. If they don't you can edit out the key that is used for google or facebook, in case one is emailAddress instead of email for example.

Upvotes: 1

Related Questions