2

I am building a website in which logging in with Google and typing email and password were working fine, but when I introduced logging in with Facebook, mongoDb is giving following error-

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

     //jshint esversion:6
require('dotenv').config();
const express = require("express");
const bodyParser = require("body-parser");
const ejs= require("ejs");
const mongoose = require("mongoose");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const FacebookStrategy = require('passport-facebook').Strategy;
const findOrCreate = require("mongoose-findorcreate");


const app = express();

console.log(process.env.API_KEY);

app.use(express.static("public"));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(session({
  secret: "Our little secret.",
  resave: false,
  saveIninitialized: false
}));

app.use(passport.initialize());
app.use(passport.session());

mongoose.connect("mongodb://localhost:27017/userDB",{ useUnifiedTopology: true });
mongoose.set("useCreateIndex", true);

const userSchema = new mongoose.Schema ({
  email: String,
  password: String,
  googleId: String,
  facebookId: String,
  secret: String
});

userSchema.plugin(passportLocalMongoose);
userSchema.plugin(findOrCreate);

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

passport.use(User.createStrategy());

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

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});
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) {
    User.findOrCreate({ googleId: profile.id }, function (err, user) {
      return cb(err, user);
    });
  }
));
passport.use(new FacebookStrategy({
    clientID: process.env.FACEBOOK_APP_ID,
    clientSecret: process.env.FACEBOOK_APP_SECRET,
    callbackURL: "http://localhost:3000/auth/facebook/secrets"
  },
  function(accessToken, refreshToken, profile, cb) {
    User.findOrCreate({ facebookId: profile.id }, function (err, user) {
      return cb(err, user);
    });
  }
));
app.get("/",function(req,res){
  res.render("home")
});
app.get('/auth/google',
  passport.authenticate('google', { scope: ['profile'] })
);
app.get('/auth/google/secrets',
  passport.authenticate('google', { failureRedirect: '/login' }),
  function(req, res) {
    // Successful authentication, redirect to secrets.
    res.redirect('/secrets');
  });
  app.get('/auth/facebook',
    passport.authenticate('facebook'));

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


app.get("/login",function(req,res){
  res.render("login")
});
app.get("/register",function(req,res){
  res.render("register")
});
...

How to solve this issue so that I can login via both google and facebook one after the other or vice-versa?

  • Does this answer your question? [E11000 duplicate key error index in mongodb mongoose](https://stackoverflow.com/questions/24430220/e11000-duplicate-key-error-index-in-mongodb-mongoose) There are a lot of similar question already answered on SOF, Please do not paste entire code base(try to give us only the part/piece of code where you're getting this issue), try to debug your code - this is very common issue which can be resolved by debugging (& error itself is self explanatory) !! – whoami - fakeFaceTrueSoul Jun 10 '20 at 00:09
  • No this doesn't answer my question – naman mathur Jun 10 '20 at 06:57
  • 1
    It looks like you changed your schema without updating the indexes. That error message indicates that there is a unique index on the field `username`, but your schema definition doesn't include that field. – Joe Jun 10 '20 at 10:50
  • Can you please tell me how to solve this, how to include that field? – naman mathur Jun 10 '20 at 11:45
  • @namanmathur : Do you still need help or resolved it ? So it that `User` model connects to `users` collection in userDB ? – whoami - fakeFaceTrueSoul Jun 10 '20 at 19:31
  • @whoami: This isn't solved yet, I need help. Yes you are right User model connects to users collection in userDB. – naman mathur Jun 10 '20 at 20:21
  • @namanmathur : If you don't need `username` field then remove index on collection !! Just run `db.users.getIndexes()` you'll see index on `username` drop it if you don't need `username` field but if you want username field then in your schema add `username : String` and are you ok to have `null` values in DB for that field ? – whoami - fakeFaceTrueSoul Jun 10 '20 at 20:24
  • I tried this but it didn't worked – naman mathur Jun 11 '20 at 11:36

1 Answers1

1

see the solution here: Setting Up Facebook Authentication with MongoDB Atlas and Passport.js

the problem is with the code above that both facebook and google users create a document in database which has no username. and MongoD set username as unique by default. so just drop the indexes from username and that solves the issue.

Fredcg
  • 13
  • 4