0

I've done a lot of research to find this answer to my problem, but I haven't discovered anything. Feel free to attach a link if I missed the answer.

I did find this solution, but I'm not exactly sure how it might apply to this situation: E11000 duplicate key error index in mongodb mongoose

I'm trying to connect my Express.js, MongoDB, Passport.js app to Mongo-Atlas. I have my Atlas cluster set up and accepting new Users from my localhost and using Google Oauth 2.0, however, when I try to register or log-in using Facebook, I get the following error.

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

Could it have something to do with this?

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

It worked when connected to my localhost MongoDB, and as I stated I'm having trouble finding a solution.

passport.use(new FacebookStrategy({
    clientID: process.env.FBAPPID,
    clientSecret: process.env.FBSECRET,
    callbackURL: "http://localhost:3000/auth/facebook/secrets"
  },
  function(accessToken, refreshToken, profile, cb) {
    console.log(profile);
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
      return cb(err, user);
    });
  }
));

app.get('/auth/facebook', passport.authenticate('facebook'));

app.get('/auth/facebook/secrets',
  passport.authenticate('facebook', { failureRedirect: '/login' }),
  function(req, res) {
    res.redirect('/secrets');
  });

UPDATE

So I've found some documentation about dropping Indexes on MongoDB However that wasn't entirely clear, so I also found an article Dropping Existing Indexes So I implemented the code into my own app.js file.

// Dropping an Index in MongoDB
User.collection.dropIndex({name : "username_1"}, function(err, res) {
    if (err) {
        console.log('Error in dropping index!', err);
    }
});

I've been dropping the Database in between testing to see if that works, but I've been getting thrown this error everything, no matter how I alter the code to try and fix it!

{ _bsontype: 'Timestamp', low_: 1, high_: 1586408833 },
  ok: 0,
  errmsg: `can't find index with key: { name: "username_1" }`,
  code: 27,
  codeName: 'IndexNotFound',
  '$clusterTime': {
    clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1586408833 },
    signature: { hash: [Binary], keyId: [Long] }
  },
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {}
}

And yet when I run db.users.getIndexes() in my Mongo Shell connected to my Atlas server. Sure enough there it is! I even tried using dropIndexes and it only dropped the email index! I am so frustrated with this!

[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "userDB.users"
    },
    {
        "v" : 2,
        "key" : {
            "email" : 1
        },
        "name" : "email_1",
        "ns" : "userDB.users",
        "background" : true
    },
    {
        "v" : 2,
        "unique" : true,
        "key" : {
            "username" : 1
        },
        "name" : "username_1",
        "ns" : "userDB.users",
        "background" : true
    }
]
  • The only thing I could come up with to fix the issue was to set username to "none" when creating a user with Facebook. This doesn't seem like the best solution. I would still like to know if there's a better option. – gfofdirtbag Apr 08 '20 at 02:35
  • So username: "none" didn't actually solve anything. I'm now at a loss! :( – gfofdirtbag Apr 08 '20 at 02:57

4 Answers4

0

You have a unique index defined on username but your code is not inserting a username (potentially because the username is not getting retrieved from the authentication provider as you are expecting). This causes multiple documents with the same value in the username filed (null).

If your users are supposed to have a username, you need to debug your code to figure out why it's not retrieving the username or passing it to MongoDB. If username is optional, remove the unique index on it.

D. SM
  • 13,584
  • 3
  • 12
  • 21
  • So I don't understand why setting my Schema email requirement to false, doesn't work. Is there somewhere else I need to check for a required field? Neither does setting the unique field to false. What am I missing? – gfofdirtbag Apr 08 '20 at 18:34
  • 1
    Not all software that creates indexes will automatically delete indexes that are not explicitly mentioned but exist in the database. To delete any index you can use database administration software like MongoDB Compass. – D. SM Apr 08 '20 at 18:54
0

Atlas Overview >> Collections >> {Collection name} >> Indexes >> Drop Index

It finally clicked! I went into the indexes tab on Atlas and deleted the required username index. Thank you for your help @oleg For some reason I couldn't find this explanation online!

Update

So deleting the index from Mongo-Atlas only temporarily solves the problem. I believe I figured out how to drop the index from my code, but I dropped it from Mongo shell already, which has seemed to solve the problem as well. So I'll provide both commands:

const User = new mongoose.model('User', userSchema);

User.collection.indexExists({ "username" : 1 }, function(err, results){
  console.log(results);
  if ( results === true) {
    // Dropping an Index in MongoDB
    User.collection.dropIndex( { "username" : 1 } , function(err, res) {
        if (err) {
            console.log('Error in dropping index!', err);
        }
    });
  } else {
    console.log("Index doesn't exisit!");
  }
});

In Mongo Shell, go into your DB and run this command:

db.users.dropIndex( { "username" : 1 } );

To confirm, run:

db.users.getIndexes() 

So many hours of research trying to solve this problem! I hope it helps you!

  • So manually deleting it only solves the issue until I run the app again. I'm adding an update to my question because the documentation I've found about dropping Indexes is not helping me. – gfofdirtbag Apr 09 '20 at 05:08
0

Go to your atlas cluster then open collections and then open indexes

and then delete username_1 index manually.

0
db.users.dropIndex( { "username" : 1 } );

This is working!!!

STA
  • 30,729
  • 8
  • 45
  • 59
DekiLaa
  • 1
  • 1