Authentication module 'Passport' requires a FindOrCreate method in order to do a login. I am using mongoose in order to save my users with the following schema:
var UserSchema = new Schema({
firstname: String,
lastname: String,
email: String,
accounts: []
});
The accounts array holds objects that represent facebook accounts, like {provider: "facebook", uid: "someFacebookId"}
.
My authentication strategy looks like this:
// Authentication Strategy
passport.use(new FacebookStrategy({
clientID: CONFIG.fb.appId,
clientSecret: CONFIG.fb.appSecret,
callbackURL: CONFIG.fb.callbackURL
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
User.find({ 'accounts.uid': profile.id, 'accounts.provider': 'facebook' }, function(err, olduser) {
if(olduser._id) {
console.log('User: ' + olduser.firstname + ' ' + olduser.lastname + ' found and logged in!');
done(null, olduser);
} else {
var newuser = new User();
var account = {provider: "facebook", uid: profile.id};
newuser.accounts.push(account);
newuser.firstname = profile.name.givenName;
newuser.lastname = profile.name.familyName;
newuser.email = "TBD...";
newuser.save(function(err) {
if(err) { throw err; }
console.log('New user: ' + newuser.firstname + ' ' + newuser.lastname + ' created and logged in!');
done(null, newuser);
});
}
});
});
}
));
Problem: After querying my database (User.find(...)
) the callback function is executed immediately without waiting for my database to answer. This results in a undefined olduser
object. So I am getting a dublicate of the same user into my database every time this user tries to login.
How do I handle this asynchronous callback properly?
User.find
returns an array of documents that match your conditions. In your case you want to use User.findOne
instead, and then check if (olduser)...
to determine if a matching doc was found.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With