Error while updating a document in MongoDB - javascript

I am having an admin portal in which I am handling all the collections that exist in my Mongo database. Now, I am building the update operations. I want to find a user that exist with his username and update the document with the changes that the admin performed.
For that reason, in my controller I have an endpoint which do the following:
exports.updateUser = async(req, res) => {
try{
var user = new User({
firstName: req.body.firstName,
lastName: req.body.lastName,
username:req.body.username,
password: req.body.password,
email: req.body.email
});
const static_username = req.body.static_username;
await User.findOneAndUpdate({static_username} , user, { useFindAndModify: false})
.then(data => {
if(!data){
res.status(404).send({ message : `Cannot Update user with ${id}. Maybe user not found!`})
}else{
res.redirect('/admin');
}
})
.catch(err =>{
res.status(500).send({ message : "Error Update user information"})
})
} catch {
console.log(err);
}
}
It takes the changes that the admin has made from the body and it puts them into user object. I also set to the variable static_username the username before update in order to find the user I to make the update.
I am getting a response that exist inside the catch of the query:
{ message : "Error Update user information"}
Error:
MongoServerError: Plan executor error during findAndModify :: caused by :: Performing an update on the path '_id' would modify the immutable field '_id'
Any thoughts why found user doesn't get updated?

You are sending a User object which has an _id field by default. So, unknowingly you are trying to modify the _id field and setting it to zero. To solve this, you can simply send a normal object.
var user = {
firstName: req.body.firstName,
lastName: req.body.lastName,
username:req.body.username,
password: req.body.password,
email: req.body.email
};

I think that the update input should contain only the fields you want to update. if username is the unique id in you User model, you would need to delete it from the user object - delete user.username - before passing it to findOneAndUpdate because an id cannot be updated. Also, as mentioned in the comments, try replacing the filter with { username: static_username}

Related

prisma findUnique with where throws an error

I am trying to create Singup API in ExpressJS and Prisma.
I am checking whether given email exists in my database or not. When I pass the email and password, it throws Unknown arg email in where.email for type SignupWhereUniqueInput. Did you mean id? Available args: error.
I tried using select: { email: true, password: true } but its not working. Code is working only if I pass id number instead of email. Any ideas what is wrong here??
router.post(`/signup`, async (req, res) => {
const { email, password } = req.body;
const hashPassword = await bcrypt.hash(password, 10);
const checkEmail = await prisma.signup.findUnique({
where: {
email: email
}
});
if (checkEmail) {
return res.status(400).json({
error: "Pick different one"
});
}
const userSignUp = await prisma.signup.create({
data: {
email,
password: hashPassword
}
});
return res.json(userSignUp);
});
// DB Schema
model Signup {
id Int #id #default(autoincrement())
email String
password String
}
The reason you're getting this error is because the email field in your Prisma Signup model is not unique. The where option in a findUnique query only accepts unique fields of a model. This is done to ensure that only one record can be specified by a findUnique query. If you're interested to know more, the Prisma Client API reference explains this behavior in some depth.
To solve the error, make the email field unique inside your Prisma Schema file. The updated Signup model should look like this:
model Signup {
id Int #id #default(autoincrement())
email String #unique
password String
}

How do I write data to firestore when creating a new user?

I'm trying to create a data entry on the firebase database to store additional information about a user when they register on my site.
I've tried to write data to the database in the .then() function following createUserWithEmailAndPassword() as that's the only way for me to extract the user id for the user (I'm hoping to use the uid as the key field of the record I create)
(req, res) => {
// extract user data from the form
const newUser = {
fname: req.body.fname,
lname: req.body.lname,
email: req.body.email,
pw: req.body.pw,
pw_c: req.body.pw_c
}
// carry out validation
const { valid, errors } = validateRegistrationData(newUser);
if (!valid) return res.status(400).json(errors);
// create new firebase user
firebase
.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.pw)
.then(data => {
let uid = data.user.uid;
// make a database entry to store the users info
// by default, assumes that the user is a secondary user
let userData = {
fname: newUser.fname,
lname: newUser.lname,
email: newUser.email,
utype: 1,
createdon: admin.firestore.FieldValue.serverTimestamp(),
intitems: []
}
newUserDoc = db
.collection("users")
.doc(uid)
.set(userData)
return res.status(200).json("Success: new user created.");
})
.catch(err => {
if (err.code === "auth/email-already-in-use"){
return res.status(400).json({ email: "Email is already in use" });
} else {
return res.status(500).json({ error: err.code });
}
});
return res.status(200).json("Success: new user created.");
}
The server responds with {Success: new user created."}. The authentication part seems to work as a new user is created in the Authentication section of my firebase console. However, no new data entries appear in the users collection of my database.
.set returns a promise that still needs to run to completion. However, currently you're not waiting on the promise, and instead just responding via res.send.
You can append .then(() => { do stuff here }) to the end of .set. If it's the last thing you're doing in that function, you can just do res.send from there.
return db.collection("users").doc(uid).set(userData).then(() => {
return res.status(200).json("Success: new user created.");
})
.catch(error => {
console.log(error)
})

Hook 'beforeUpdate' in a sequelize model issue

I am developing an API with nodejs/express/sequelize.
Actually when I am creating an user account. I got a Hook 'beforeCreate' which hash the user password thanks to bcrypt :
User.hook('beforeCreate', (user) => {
if (user.password) {
user.password = bcrypt.hashSync(user.password, bcrypt.genSaltSync(10), null);
}
});
where user.password is the password I provided when registered.
This part is working well.
Secondly I got a function which update this user account. Logically I added a hood 'beforeUpdate' :
User.hook('beforeUpdate', (user) => {
console.log(user);
if (user.password) {
user.password = bcrypt.hashSync(user.password, bcrypt.genSaltSync(10), null);
}
});
But I got an issue with that one because user.password is not my provided data in the PATCH request but the hashed password in my database.
I guess it is the model password and not the instance password... I don't know.
If someone could help me to get the query value it would be nice.
You can use _previousDataValues
User.hook('beforeUpdate', (user) => {
console.log(user);
if (user.password) {
user.password = bcrypt.hashSync(user.previous.password, bcrypt.genSaltSync(10), null);
}
});

Error while Inserting record through node into MySQL database

I am new in Node and trying to develop some initial apps. I am currently inserting record into database(MySQL) through Node. My post method is like
router.post('/add',function(req,res){
connection.connect();
var firstName = req.body.FirstName;
var lastName = req.body.LastName;
students.push({
//id: studentList.length+1,
FirstName: firstName,
LastName: lastName
});
var post = {FirstName: firstName, LastName: lastName};
connection.query('INSERT INTO tblstudent VALUES ? ', post,function(err,result){
if (err) {
res.send("There was a problem adding the information to the database.");
}
});
res.redirect('/');
connection.end();
});
where Id is another column but auto incremented, so I trying to insert record. I'm having the following error.
Error: Can't set headers after they are sent
This error means that headers where already set but one more is trying to be set up.
In your case, you have called res.redirect(), making the response finished. Then your code threw an error because query has failed, and you`ve tried to set a response:
"res.send("There was a problem adding the information to the database.");".
In order to fix the problem you should move res.redirect('/'); in to callback function of the query.
connection.query('INSERT INTO tblstudent VALUES ? ', post,function(err,result){
if (err) {
res.send("There was a problem adding the information to the database.");
} else {
res.redirect('/');
}
});

Mongoose NodeJS only undefined values [duplicate]

This question already has answers here:
Mongoose always returning an empty array NodeJS
(7 answers)
Closed 7 years ago.
Now I've played with nodeJS and SocketIO and all went fine.
But now I get caught at one query!
// User Auth Event
socket.on('userAuth', function(userObj) {
var queryUserAuth = User.find({
name : userObj.name
})
.where('password',userObj.pword);
queryUserAuth.exec(function(err, userData){
if(err) {
socket.emit('userAuthOK',err);
console.log('!! User: %s or PW not OK', userObj.name);
return handleError(err);
}else {
console.log('User: %s known, userID: %s', userObj.name, userData.userid);
socket.emit('userAuthOK', userData.userid);
socket.join(userData.userid); // Create new room / join this room
}
});
});
But all the time the var "userData" is empty and the console.log above tells me "User: testuser known, userID: undefined".
I can't get this user object from MongoDB this ways, but I can find the user if I take the mongo console.
///////////
EDIT:
After some changes... here the new code... but still without finding the right record and getting a result of null.
// User Auth Event
socket.on('userAuth', function(userObj) {
var queryUserAuth = User.findOne({
name : userObj.name,
password : userObj.pword
});
//.where("password").equals(userObj.pword);
queryUserAuth.exec(function(err, userData){
if(err) {
socket.emit('userAuthOK',err);
console.log('!! User Auth Error: %s', err);
return handleError(err);
}else {
if(!userData){
console.log('!! User: %s or PW not OK.', userObj.name);
socket.emit('userAuthOK','fail');
}else {
console.log('User: %s known, userID: %s', userObj.name, userData);
socket.emit('userAuthOK', userData);
socket.join(userData.userid); // Create new room / join this room
}
}
});
});
Here the output by manual query on mongo shell:
db.user.find({name: 'testuser', password: 'test'}) { "_id" : ObjectId("55a8cc8240fdc97f108d4d11"), "userid" : "1", "name" : "testuser", "email" : "test#test.com", "password" : "test" }
And this is the value of userObj: { name: 'testuser', pword: 'test' }
/////
EDIT2:
here the user.js including the mongoose model of User:
// Load the MongoDB module
var mongoose = require('mongoose');
// user schema
var userSchema = mongoose.Schema({
userid: Number,
name: String,
email: String,
password: String,
status: Number
});
// compiling the user schema
var User = mongoose.model('User', userSchema);
// make this available to our users in our Node applications
module.exports = User;
Here the include of the model:
// Load Mongoose models
var User = require('./models/user');
Try logging userData instead of just userData.userid. It's an Array, not an Object. You want to use .findOne(), not .find().
Also, the syntax for the query methods is:
.where("password").equals(userObj.pword)
Or, you could just add it to your original .findOne():
var queryUserAuth = User.findOne({
name: userObj.name,
password: userObj.pword
});
In addition, your console.log('!! User: %s or PW not OK', userObj.name); doesn't make any sense. Not finding anyone is different than getting an error. You'll want to handle that part as a separate if statement nested within the else block.

Categories

Resources