user4080876
user4080876

Reputation:

User.findOrCreate is not a function passport-facebook

I have followed the github guide of passport-facebook and this is the result I've been getting:

User.findOrCreate is not a function

I have this code in my passport.js:

passport.use(new FacebookStrategy({
    clientID        : configAuth.facebookAuth.clientID,
    clientSecret    : configAuth.facebookAuth.clientSecret,
    callbackURL     : configAuth.facebookAuth.callbackURL
    },
    function(accessToken, refreshToken, profile, done) {
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
    return done(err, user);
    });
    }
));

Do I need to write the findOrCreate method myself? I thought mongoose was handling this?

Also, what does profile.id do? Do I need to edit that to something relevant to my code? I don't have a model named profile.

This is my user model:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var crypto = require('crypto');
var jwt = require('jsonwebtoken');

var UserSchema = new mongoose.Schema({
    username: { type: String, lowercase: true, unique: true },
    firstname: { type: String},
    lastname: { type: String},
    difficulty: { type: String},
    isstudent: { type: Boolean },
    haschildren: { type: Boolean},
    gender: { type: String },
    email: { type: String, unique: true},
    birthdate: String,
    isdoingchallenges: { type: Boolean },
    challengescompleted: [{ type: ObjectId, ref: 'Challenge' }],
    currentchallenge: { type: ObjectId, ref: 'Challenge' },
    challengessuggestions: [{ type: ObjectId, ref: 'Challenge' }],
    isfacebooklogin:{type:Boolean},
    facebookid:{type:String},
    hash: String,
    salt: String
});

UserSchema.methods.setPassword = function(password){
    this.salt = crypto.randomBytes(16).toString('hex');
    this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex');
};

UserSchema.methods.validPassword = function(password) {
    var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex');
    return this.hash === hash;
};

UserSchema.methods.generateJWT = function() {

    // set expiration to 60 days
    var today = new Date();
    var exp = new Date(today);
    exp.setDate(today.getDate() + 60);

    return jwt.sign({
        _id: this._id,
        username: this.username,
        exp: parseInt(exp.getTime() / 1000),
    }, 'SECRET');
};

mongoose.model('AppUser', UserSchema);

Upvotes: 2

Views: 7153

Answers (3)

Ashish Bamania
Ashish Bamania

Reputation: 41

  1. Use the function by installing mongoose-findorcreate package with npm.

npm install mongoose-findorcreate

  1. Declare it in your code.

const findOrCreate = require("mongoose-findorcreate");

  1. When you create your schema, add the function as a plugin to use it.

yourSchema.plugin(findOrCreate);

Viola! It's done!

Upvotes: 4

Amol M Kulkarni
Amol M Kulkarni

Reputation: 21639

This is how you can add a static method on your mongoose schema/model

userSchema.statics.findOrCreate = function findOrCreate(profile, cb){
    var userObj = new this();
    this.findOne({_id : profile.id},function(err,result){ 
        if(!result){
            userObj.username = profile.displayName;
            //....
            userObj.save(cb);
        }else{
            cb(err,result);
        }
    });
};

Upvotes: 2

Adel Skhiri
Adel Skhiri

Reputation: 1

yes make your own findOrCreate method containing a User.findOne({facebookID:profile.id},callback) then if findOne have no results a User.Create({facebookID : profile.id , username : profile.displayName ...}) . you should add facebookID on your schema, if not you will create a user for each facebook connection.

Upvotes: 0

Related Questions