My code was working before initially but I don’t know why it just stopped working and gave me this error:
MongooseError: Operation `users.findOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (/Users/nishant/Desktop/Yourfolio/backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:184:20)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7)
I am trying to authenticate the user by login with JWT. My client runs fine but in my backend I get this error. My backend code:
import neuron from '@yummyweb/neuronjs'
import bodyParser from 'body-parser'
import cors from 'cors'
import mongoose from 'mongoose'
import emailValidator from 'email-validator'
import passwordValidator from 'password-validator'
import User from './models/User.js'
import Portfolio from './models/Portfolio.js'
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
import auth from './utils/auth.js'
// Dot env
import dotenv from 'dotenv'
dotenv.config()
// Custom Password Specifications
// Username Schema
const usernameSchema = new passwordValidator()
usernameSchema.is().min(3).is().max(18).is().not().spaces()
// Password Schema
const passwordSchema = new passwordValidator()
passwordSchema.is().min(8).is().max(100).has().uppercase().has().lowercase().has().digits().is().not().spaces()
const PORT = process.env.PORT || 5000
const neuronjs = neuron()
// Middleware
neuronjs.use(bodyParser())
neuronjs.use(cors())
// Mongoose Connection
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true }, () => console.log("MongoDB Connected"))
// API Routes
neuronjs.POST('/api/auth/signup', async (req, res) => {
const { username, email, password, passwordConfirmation } = req.body
// Validation: all fields are filled
if (!username || !email || !password || !passwordConfirmation) {
return res.status(400).json({
"error": "true",
"for": "fields",
"msg": "fill all the fields"
})
}
// Validation: username is valid
if (usernameSchema.validate(username, { list: true }).length !== 0) {
return res.status(400).json({
"error": "true",
"for": "username",
"method_fail": usernameSchema.validate(username, { list: true }),
"msg": "username is invalid"
})
}
// Validation: email is valid
if (!emailValidator.validate(email)) {
return res.status(400).json({
"error": "true",
"for": "email",
"msg": "email is invalid"
})
}
// Validation: password is valid
if (passwordSchema.validate(password, { list: true }).length !== 0) {
return res.status(400).json({
"error": "true",
"for": "password",
"method_fail": passwordSchema.validate(password, { list: true }),
"msg": "password is invalid"
})
}
// Validation: password is confirmed
if (password !== passwordConfirmation) {
return res.status(400).json({
"error": "true",
"for": "confirmation",
"msg": "confirmation password needs to match password"
})
}
// Check for existing user with email
const existingUserWithEmail = await User.findOne({ email })
if (existingUserWithEmail)
return res.status(400).json({ "error": "true", "msg": "a user already exists with this email" })
// Check for existing user with username
const existingUserWithUsername = await User.findOne({ username })
if (existingUserWithUsername)
return res.status(400).json({ "error": "true", "msg": "a user already exists with this username" })
// Generating salt
const salt = bcrypt.genSalt()
.then(salt => {
// Hashing password with bcrypt
const hashedPassword = bcrypt.hash(password, salt)
.then(hash => {
const newUser = new User({
username,
email,
password: hash
})
// Saving the user
newUser.save()
.then(savedUser => {
const newPortfolio = new Portfolio({
user: savedUser._id,
description: "",
socialMediaHandles: {
github: savedUser.username,
dribbble: savedUser.username,
twitter: savedUser.username,
devto: savedUser.username,
linkedin: savedUser.username,
}
})
// Save the portfolio
newPortfolio.save()
// Return the status code and the json
return res.status(200).json({
savedUser
})
})
.catch(err => console.log(err))
})
.catch(err => console.log(err))
})
.catch(err => console.log(err))
})
neuronjs.POST('/api/auth/login', async (req, res) => {
try {
const { username, password } = req.body
// Validate
if (!username || !password) {
return res.status(400).json({ "error": "true", "msg": "fill all the fields", "for": "fields", })
}
const user = await User.findOne({ username })
if (!user) {
return res.status(400).json({ "error": "true", "msg": "no account is registered with this username", "for": "username" })
}
// Compare hashed password with plain text password
const match = await bcrypt.compare(password, user.password)
if (!match) {
return res.status(400).json({ "error": "true", "msg": "invalid credentials", "for": "password" })
}
// Create JWT token
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET)
return res.json({ token, user: { "id": user._id, "username": user.username, "email": user.email } })
}
catch (e) {
console.log(e)
}
})
// Delete a user and their portfolio
neuronjs.DELETE("/api/users/delete", async (req, res) => {
auth(req, res)
const deletedPortfolio = await Portfolio.findOneAndDelete({ user: req.user })
const deletedUser = await User.findByIdAndDelete(req.user)
res.json(deletedUser)
})
neuronjs.POST("/api/isTokenValid", async (req, res) => {
const token = req.headers["x-auth-token"]
if (!token) return res.json(false)
const verifiedToken = jwt.verify(token, process.env.JWT_SECRET)
if (!verifiedToken) return res.json(false)
const user = await User.findById(verifiedToken.id)
if (!user) return res.json(false)
return res.json(true)
})
// Getting one user
neuronjs.GET("/api/users/user", async (req, res) => {
auth(req, res)
const user = await User.findById(req.user)
res.json({
"username": user.username,
"email": user.email,
"id": user._id
})
})
// Getting the porfolio based on username
neuronjs.GET("/api/portfolio/:username", async (req, res) => {
try {
const existingUser = await User.findOne({ username: req.params.username })
// User exists
if (existingUser) {
const userPortfolio = await Portfolio.findOne({ user: existingUser._id })
return res.status(200).json(userPortfolio)
}
// User does not exist
else return res.status(400).json({ "error": "true", "msg": "user does not exist" })
}
catch (e) {
console.log(e)
return res.status(400).json({ "error": "true", "msg": "user does not exist" })
}
})
// Update Portfolio info
neuronjs.POST("/api/portfolio/update", async (req, res) => {
auth(req, res)
// Find the portfolio
const portfolio = await Portfolio.findOne({ user: req.user })
// Then, update the portfolio
if (portfolio) {
// Call the update method
const updatedPortfolio = await portfolio.updateOne({
user: req.user,
description: req.body.description,
socialMediaHandles: req.body.socialMediaHandles,
greetingText: req.body.greetingText,
navColor: req.body.navColor,
font: req.body.font,
backgroundColor: req.body.backgroundColor,
rssFeed: req.body.rssFeed,
displayName: req.body.displayName,
layout: req.body.layout,
occupation: req.body.occupation
})
return res.status(200).json(portfolio)
}
})
neuronjs.listen(PORT, () => console.log("Server is running on port " + PORT))
The auth.js file function:
import jwt from 'jsonwebtoken'
const auth = (req, res) => {
const token = req.headers["x-auth-token"]
if (!token)
return res.status(401).json({ "error": "true", "msg": "no authentication token" })
const verifiedToken = jwt.verify(token, process.env.JWT_SECRET)
if (!verifiedToken)
return res.status(401).json({ "error": "true", "msg": "token failed" })
req.user = verifiedToken.id
}
export default auth
Any help is much appreciated and I have already tried a few solutions like deleting node_modules and re installing mongoose.
17
Answers
After Creating Cluster click connect and add your IP or add another IP in the MongoDB Atlas
According to Documentation found in this link: https://mongoosejs.com/docs/connections.html#buffering
TL;DR:
Your model is being called before the connection is established. You need to use async/await with connect() or createConnection(); or use .then(), as these functions return promises now from Mongoose 5.
In my experience this happens when your database is not connected, Try checking out following things –
mongoose.connect(...)
code is loading.I faced this issue where I was running the
node index.js
from my terminal and mongoose connect code was into different file. After requiring that mongoose code in index.js it was working again.mongoose.connect('mongodb://localhost/myapp', {useNewUrlParser: true});
Just do this add
{useNewUrlParser: true}
in connection file.This error[
user.findOne()
] showing because yourconfig
package version is updated automatically.Enter the following in your terminal:
or
I’ve run into this a number of times; particularly when I’ve upgraded nested dependancies that require mongoose. This always does the trick for me.
My code worked normaly from one PC but from another one I got the same error. I have MongoDB free hosting by https://www.mongodb.com/ .
I fixed it by adding my current IP to
Security - Network Access - IP Access List
in the hosting server.I had the same problem. In my case, I had kept mongoose.connect statement in a different file and forgot to invoke it while writing the require statement.
I had done this in my index.js file and changed it to this
There was already a Cluster , collection made in my mongo db atlas , all i had to do was clear that out and send another post request to make it work .
I had the same issue when using Mongoose 6. I connected to Mongoose in my index.js file the following way:
I found the following info for Mongoose 6 in their site:
When I removed the
useCreateIndex: true
option the issue was solved.I just had this issue myself when I tried to use my database while my server was in error and mongoose created a huge 87 part error panel that I had to sift through and when I did, I found that the options that I passed to mongoose were depreciated. So if you can scroll to where you start your server, you may see details telling you to remove or append certain options. Removing the extra options fixed my issue.
Make sure that you’re connecting to MongoDB at the top of your function(inside file) and doing (CRUD) operations after connecting to MongoDB Atlas.
Hope that makes sense.
I was getting error because in my file I’m loading data from other server and inserting into my MongoDB after that asynchronous operations I’m connecting to my MongoDB Server, that’s why I was getting error.
CORRECT ↓
INCORRECT ↓
I think the reason is that your IP address is not whitelisted for your db. Check for it if you have a problem like this.
It worked for me after I used this code, in my
app.js
file:And removed all the four mongoose options below from my code:
If you are trying to run the project from another network or Ip, make sure you whitelist your ip in mongoDB atlas.
Simply go to Network tab> Add ip address.
Allow
Network Access
from everywhere.Please note that this is a temporary solution.
What this error is trying to say is that it cannot access the MongoDB collection. This may be mostly because of these 2:
If you are importing the database connect string from .env file, make sure that the .env file is in the root folder where you are running the
npm run
command.I’ve tried all the solutions here to no awail. Suddenly I realized that the .env file was in /server folder, which is one folder deeper than my project root folder.
Make sure you move
.env
file to project root folder!! To get theprocess.env.DB_CONNECT
for example.