I'm having this issue. I made a login system which works like that:
Login with Discord
If exists - if user changed their Discord information, update and return user information. If they didn't change any of their Discord account information, just return user information
If doesn't exist - create user and return user information
That's my user.js schema:
import mongoose from 'mongoose';
const Schema = mongoose.Schema
const userSchema = new Schema({
userId: {type: String, required: true, unique: true},
username: {type: String, required: true, unique: false},
type: {type: String, required: true},
discrim: {type: String, required: true},
email: {type: String, required: true},
avatar: {type: String, required: true},
banned: {type: Boolean, required: true}
})
const User = mongoose.model('User', userSchema)
export default User
And there's login system login (just a prototype to show the problem):
app.post("/login-test", (req, res) => {
User.findOne({"userId": req.body.uid}).then((result) => {
console.log(result)
if(result == null){
const newUser = new User({
userId: req.body.uid,
username: "sharek1234",
discrim: "1236",
email: "sharekxass#gmail.com",
avatar: "bereknone",
banned: false,
type: "user"
})
newUser.save().then((resp) => {
res.json(resp)
})
}else{
User.updateOne({"userId": req.body.uid}, {
discrim: "1236",
email: "sharekxass#gmail.com",
avatar: "bereknone",
banned: false,
type: "user"
}).then((resp) => {
res.json(resp)
}).catch((pog) => {
console.log(pog)
res.json(pog)
})
}
})
})
But when I try to log in with existing user after Discord account information change, where other user with name "MyName123" already exists, for example:
Before change:
UserID: "12345"
Username: "MyName"
Discrim: "1000"
After change:
UserID: "12345"
Username: "MyName123"
Discrim: "9999"
it returns E11000 error.
E11000 duplicate key error collection: ShardDB.users index: username_1 dup key: { username: "MyName123" }. Please note that username field in userSchema is not unique.
I have no idea how to fix this.
I solved this, I don't know why but there was "username_1" index in my database, and it was set to unique. I deleted it and now everything works fine.
Related
I am attempting to log a user in to my DB. When I log the user in, it returns the first userId in the DB and not the user who logged in. I have been struggling with this for a while and really am at a dead end.
This is my POST route to log the user in:
// login
router.post("/login", async (req, res) => {
const user = await User.findOne({
email: req.body.email,
});
const secret = process.env.SECRET;
if (!user) {
return res.status(400).send("the user not found!");
}
if (user && bcrypt.compareSync(req.body.password, user.passwordHash)) {
const token = jwt.sign(
{
userId: user.id,
isAdmin: user.isAdmin,
},
secret,
{ expiresIn: "1d" }
);
res.status(200).send({ user: user.email, token: token });
} else {
res.status(400).send("password is wrong!");
}
});
The const user = await User.findOne({ email: req.body.email, }); this returns the wrong user.
When I query the endpoint get a users profile with the userId it gets the right information. So its got nothing to do with the DB.
This is the call in the app.
const handleSubmit = () => {
axios
.post(`${baseURL}users/login`, {
email: email,
passwordHash: password,
})
.then(res => {
console.log('USER ID TOKEN', res.data.token);
setbearerToken(res.data.token);
AsyncStorage.setItem('bearerToken', res.data.token);
const decoded = decode(res.data.token);
setTokenID(decoded.userId);
dispatch(setUser(res.data));
});
};
user.js model
const userSchema = mongoose.Schema({
contactName: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
phone: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
passwordHash: {
type: String,
required: true,
minlength: 5,
maxlength: 1024
},
token: {
type: String,
},
isAdmin: {
type: Boolean,
default: false
},
clubName: {
type: String,
required: true,
},
clubAddress: {
type: String,
required: true,
},
clubEmail: {
type: String,
required: true,
},
clubPhone: {
type: String,
required: true,
},
clubWebsite: {
type: String,
required: true,
},
clubContact: {
type: String,
required: true,
},
})
Your schema doesn't have a field email to filter on.
const user = await User.findOne({
email: req.body.email,
});
Maybe you try clubEmail field. I reproduced the behavior and it looks like that mongoose ignores the filter if the field does not exist in the Schema an just returns the first document in the collection.
E.g.
const userSchema = new Schema(
{
name: String,
age: Number
}
)
const User = mongoose.model('User', userSchema);
User.findOne({name: "Superman"}, ...
Returns the user with name "Superman".
const userSchema = new Schema(
{
name: String,
age: Number
}
)
const User = mongoose.model('User', userSchema);
User.findOne({xname: "Superman"}, ...
But when using xname in the filter document which does not exist in my schema neither in the collection as field the query returns the first document in my test collection (its not Superman).
Also look here similar issue: Model.find Mongoose 6.012 always return all documents even though having filter
Issue reported: https://github.com/Automattic/mongoose/issues/10763
Migration Guide to Mongoose 6:
https://mongoosejs.com/docs/migrating_to_6.html#strictquery-is-removed-and-replaced-by-strict
I have the following schema for a mongoose model:
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'User must have a name'],
unique: true
},
photo: String,
password: {
type: String,
required: [true, 'User must have a passwod'],
select: false,
minlength: 8
},
passwordConfirm: {
type: String,
required: ['Please confirm the passwod'],
select: false,
validate: {
validator: function(val) {
return this.password === val;
},
message: 'Password and passwordConfirm do not match'
}
}
});
Since password is set as Select:false, it should not be present in the queried object. However, when i create a document as below, it always has the password present:
const user = await userModel.create({
name: req.body.name,
email: req.body.email,
password: req.body.password,
passwordConfirm: req.body.passwordConfirm
});
hi i am new to developing a mean stack project, my task that im stuck at is i have two collections one as user for admin and other for center for vaccine center my task is to register an admin to a healthcare center but im not sure how to link these as the admin is required to see healthcare centers that are registered select and then register them into the center
user.js (mongoose schema)
,,,
const userSchema = mongoose.Schema({
username: {type: String, required: true, unique: true},
password: {type: String, required: true},
fullname: {type: String, required: true},
email: {type: String, required: true},
staffid: {type: String, required: true, unique: true},
center: {type: String, required: true},
});
userSchema.plugin(uniqueValidator);
module.exports = mongoose.model('User', userSchema);
,,,
center.js
,,,
const mongoose = require('mongoose');
const postSchema = mongoose.Schema({
cname: {type: String, required: true},
caddr: {type: String, required: true}
});
module.exports = mongoose.model('Centers', postSchema);
,,,
user.model.service
,,,
export interface User{
id: string;
fname: string;
uname: string;
email: string;
pass: string;
staffid: string;
center: string;
}
,,,
signup-component.html (i plan to display the list of center names as dropdown so the admin can select center name when they register the account)
,,,
<mat-form-field appearance="fill">
<mat-label>Select</mat-label>
<mat-select >
<mat-option name="center" *ngFor="let post of posts" value="post">{{post.cname}}</mat-option>
</mat-select>
,,,
app.js
,,,
app.post('/api/user/signup', (req, res, next) => {
bcrypt.hash(req.body.password, 10)
.then(hash => {
const user = new User ({
username: req.body.username,
password: hash,
fullname: req.body.fullname,
email: req.body.email,
staffid: req.body.staffid,
center: req.body.center
});
user.save()
.then(result => {
res.status(201).json({
message: 'user registered',
result: result
});
})
.catch(err =>{
res.status(500).json({
error:err
});
});
});
});
,,,
From what you describe, I think you need three database tables or three mongoose.Schemas:
one for the vaccination centers: like in your center.js
one for the (admin) users: like in your user.js, but without the center property
and one for assignment of users to centers:
mongoose.Schema({
user: {type: schema.type.objID, ref: "Users", required: true},
center: {type: schema.type.objID, ref: "Centers", required: true}
});
The extra association schema is needed if one user can be assigned to several vaccination centers.
Does that help with your requirements?
currently building notes-app project where we can save notes and can edit and delete notes also..
suddenly got stuck here... i want to query ( findById ) all the documents that matches with user id.. in this case i referenced user id as postedBy in Notes Schema..
here is my user schmea or model...
import mongoose from 'mongoose'
const userSchema = new mongoose.Schema({
username: {
type: String,
required: [true, 'please provide username'],
},
email: {
type: String,
required: [true, 'please provide email'],
unique: true,
index: true,
},
password: {
type: String,
required: [true, 'please provide password'],
},
accountCreatedAt: {
type: String,
default: Date,
},
})
const User = mongoose.model('User', userSchema)
export default User
here goes my notes Schema and i referenced user id as ref :
import mongoose from 'mongoose'
const noteSchema = new mongoose.Schema(
{
title: {
type: String,
required: [true, 'please provide title'],
unique: true,
trim: true,
},
text: {
type: String,
trim: true,
required: [true, 'Please provide text'],
},
lable: {
type: String,
required: [true, 'please provide lable'],
},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
},
{
timestamps: { createdAt: 'created_At', updatedAt: 'updated_At' },
}
)
const Note = mongoose.model('Note', noteSchema)
export default Note
route and controller function:
noteRoutes.get('/getNotesByUserID/:_id', noteController.getNotesByUserID)
export const getNotesByUserID = async (req, res, next) => {
try {
const id = req.params._id
const userNotes = await Note.findById({ postedBy: id })
res.status(200).json({
status: 'success',
data: {
userNotes,
},
})
} catch (error) {
res.status(400).json({
status: 'error',
data: {
message: error.message,
},
})
}
}
when i tried to test this in postman i'm getting the below message :
*"message": "Cast to ObjectId failed for value \"{ postedBy: '609554f9560327264b23d3fe' }\" at path \"_id\" for model \"Note\""*
thanks in advance...
mongoose findById method casts the id parameter to the type of the model's _id field, in your case this field is an ObjectID type.
You however are passing the id argument as an object { postedBy: '609554f9560327264b23d3fe' } then mongoose tries to do the following:
const castId = new ObjectId({ postedBy: '609554f9560327264b23d3fe' })
This fails for obvious reasons.
Because findById is a customized method to "quickly" find documents by their _id field you shouldn't be using it to query a different field. In your cast you should be using findOne instead.
const userNotes = await Note.findOne({ postedBy: id })
here is my Schema code
var Schema = mongoose.Schema;
var UserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
phone:{
type: String,
required: true
},
password: {
type: String,
required: true
},
createdAt: {type: Date, default: Date.now}
});
and I am inserting the data as it is shown below (inside another file)
router.route('/register')
.post(function(req, res) {
var registeration = new Registeration({
username: req.body.username,
phone: req.body.phone,
password: req.body.password
});
registeration.save(function(err) {
if (err){
return res.json({ success: false, message: 'That username already exists.'});
}
res.json({ success: true, message: 'Successfully created new user.' });
})
});
The problem here is that, whenever I register new account it is successfully added even if the username already exists in my database
I set the attribute to unique: true but it doesn't seem to work for some reason.
What am I doing wrong here?