londonappbrewery / Authentication-Secrets

Companion Code for the Authentication Module on The Complete 2019 Web Development Bootcamp
https://www.appbrewery.co
440 stars 524 forks source link

MongoError: E11000 duplicate key error collection: userDB.users index: username_1 dup key: { username: null } #2

Open himanshuclub88 opened 5 years ago

himanshuclub88 commented 5 years ago

when I try to add my second email I got eroor

Ashutosh1109 commented 4 years ago

Same with me

Ashutosh1109 commented 4 years ago

when I try to add my second email I got eroor

did your error got fixed

getspooky commented 4 years ago

he reason behind this error is that. The index is not present in your collection, in which you are trying insert. So Solution is to drop that collection and run your program again

pakiZBRG commented 4 years ago

getspooky How to drop a collection?

IMZILEN commented 4 years ago

db.collectionname.drop()

getspooky How to drop a collection?

Sujithk007 commented 4 years ago

I was also facing the same problem. I fixed it by just changing 2 line of code. By adding the email field in :

passport.use(new GoogleStrategy({ clientID: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/secrets", userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo" }, function(accessToken, refreshToken, profile, cb) { console.log(profile); User.findOrCreate({ username: profile.emails[0].value, googleId: profile.id, }, function (err, user) { return cb(err, user); }); } ));

and also in :

app.get('/auth/google', passport.authenticate('google', { scope: ['profile',"email"] }));

naresh4dev commented 3 years ago

Actually, the package mongoose-findorcreate implicitly passes two arguments(ID and Username) to the mongo server, When you tap into the first user, You store only the "ID" of the user, So the findorcreate package assigns null value to the username field. Again when you try to tap into second or multiple users, Since you already set a null value to the username field. MongoDB server allows only one entry of the null valued field. So It will throw an error.

Here is the solution. Replace the existing package function of findorcreate with the below code

User.findOne( {googleId : profile.id}, function( err, foundUser ){
    if( !err ){                                                          //Check for any errors
        if( foundUser ){                                          // Check for if we found any users
            return cb( null, foundUser );                  //Will return the foundUser
        }else {                                                        //Create a new User
            const newUser = new User({
                googleId : profile.id
            });
            newUser.save( function( err ){
                if(!err){
                    return cb(null, newUser);                //return newUser
                }
            });
        }
    }else{
        console.log( err );
    }
});

Finally by adding this code may solve your issue. Also, remove the findorcreate plugin to your userSchema.

AbdullahGumi commented 3 years ago

That happened to me when i changed a collection's schema which already had documents and tried adding new documents with the new type of schema. The solutions was to delete the collection because it had different types of schema.

fatmaElsheikh commented 3 years ago

you have to add to your schema googled const userSchema = new mongoose.Schema({ email: String, password: String, googleId: String }) drop the collection and try again

alta-max commented 3 years ago

i had the same problem and i fixed it by adding a username to my entries, here's my code passport.use(new GoogleStrategy({ clientID: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/home" }, function(accessToken, refreshToken, profile, cb) { console.log(profile); User.findOrCreate({ username: profile.displayName, googleId: profile.id }, function (err, user) { return cb(err, user); }); } )); see the username:profile.displayName in findorcreate, now all your entrues have a username so it wont show username=null

rolfikv commented 3 years ago

I was also facing the same problem. I fixed it by just changing 2 line of code. By adding the email field in :

passport.use(new GoogleStrategy({ clientID: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/secrets", userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo" }, function(accessToken, refreshToken, profile, cb) { console.log(profile); User.findOrCreate({ username: profile.emails[0].value, googleId: profile.id, }, function (err, user) { return cb(err, user); }); } ));

and also in :

app.get('/auth/google', passport.authenticate('google', { scope: ['profile',"email"] }));

Thanks for the solution, but can you explain or share a link to understand why this works?

mohit-codes commented 3 years ago

I had the same issue, I deleted the respective collection from database and recreated it. Issue resolved.

Hacky-byte commented 3 years ago

I added 'email' as an argument in the callback function and it worked fine

passport.use(new GoogleStrategy({ clientID: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/home" }, function(accessToken, refreshToken, profile, email , cb) { console.log(profile); User.findOrCreate({ username: profile.displayName, googleId: profile.id }, function (err, user) { return cb(err, user); }); } ));

But on later steps you have to remove other changes to store googleId in schema for which one has to edit the schema ny adding a field later :

googleId : String

removing the above changes

xwilliam89 commented 3 years ago

I have experienced the same issue. After some googling, I simply drop my "users" collection. Then everything just works fine. I still don't know what was the cause.

MaxBay2020 commented 2 years ago

he reason behind this error is that. The index is not present in your collection, in which you are trying insert. So Solution is to drop that collection and run your program again

Thank god! This works to me!

HakzTV commented 2 years ago

That happened to me when i changed a collection's schema which already had documents and tried adding new documents with the new type of schema. The solutions was to delete the collection because it had different types of schema.

I have experienced the same issue. After some googling, I simply drop my "users" collection. Then everything just works fine. I still don't know what was the cause.

Hey, sorry but none of the solutions are working for me

BlcaKHat commented 2 years ago

just add another field in the mongoose schema along with googleId. like this. {username: profile.displayName, googleId: profile.id }, and it should work. also try to drop the collection and rerun the application i it doesn't work.

KamilKasiak commented 2 years ago

Just modify your findOrCreate inputs like this: function(accessToken, refreshToken, profile, cb) { User.findOrCreate({ username: profile.id, googleId: profile.id }, function (err, user) { return cb(err, user);});} Set username: profile.id since it is unique. I had some issues when used "username: profile.displayName" an diferent social media strategies.

repo-by-anish commented 2 years ago

he reason behind this error is that. The index is not present in your collection, in which you are trying insert. So Solution is to drop that collection and run your program again

Still getting Same error.

farrelcodes commented 1 year ago

I figured out that this problem may caused by the indexes which automatically set by the database. You can remove the username_1 index in the database, and eventually this problem will no longer exists. Hope it helps!

prechy123 commented 1 year ago

getspooky How to drop a collection?

this will work, i was facing the same issue and dropping the collection fixed it

YegetaTaye commented 12 months ago

getspooky How to drop a collection?

db.collectionName.drop()

guda-art commented 8 months ago

Create a collection using code instead of using client software