Мой код работал раньше, но я не знаю, почему он просто перестал работать и выдал мне эту ошибку:
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)
Я пытаюсь аутентифицировать пользователя, войдя в систему с помощью JWT. Мой клиент работает нормально, но в моем бэкэнде я получаю эту ошибку. Мой внутренний код:
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.info("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.info(err))
})
.catch(err => console.info(err))
})
.catch(err => console.info(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.info(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.info(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.info("Server is running on port " + PORT))
Функция файла auth.js:
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
Любая помощь очень ценится, и я уже пробовал несколько решений, таких как удаление node_modules и повторная установка mongoose.
После создания кластера нажмите «Подключиться» и добавьте свой IP-адрес или добавьте другой IP-адрес в Атлас MongoDB.
Согласно документации, найденной по этой ссылке: https://mongoosejs.com/docs/connections.html#buffering
Mongoose позволяет сразу же начать использовать свои модели, не дожидаясь, пока mongoose установит соединение с MongoDB.
Это потому, что мангуст буферизирует вызовы функций модели внутри. Этот буферизация удобна, но также является распространенным источником путаницы. Mongoose не будет выдавать никаких ошибок по умолчанию, если вы используете модель без подключения.
TL;DR:
Ваша модель вызывается до установления соединения. Вам нужно использовать async/await с connect() или createConnection(); или используйте .then() , так как эти функции теперь возвращают промисы из Mongoose 5.
По моему опыту, это происходит, когда ваша база данных не подключена. Попробуйте проверить следующие вещи:
mongoose.connect(...)
.Я столкнулся с этой проблемой, когда запускал node index.js
из своего терминала, а код подключения мангуста находился в другом файле. После запроса этого кода мангуста в index.js он снова заработал.
mongoose.connect('mongodb://localhost/myapp', {useNewUrlParser: true});
Просто добавьте {useNewUrlParser: true}
в файл подключения.
Если вы проверите исходный вопрос, то ясно увидите, что {useNewUrlParser: true}
уже добавлено.
Опция также не нужна в последней версии Mongoose.
Эта ошибка [user.findOne()
] отображается, потому что ваша версия пакета config
обновляется автоматически.
Введите следующее в свой терминал:
npm i -E [email protected]
или
yarn add -E [email protected]
У вас есть ссылка на это?
Я сталкивался с этим несколько раз; особенно когда я обновил вложенные зависимости, для которых требуется mongoose. Это всегда помогает мне.
rm -rf node_modules
rm package-lock.json
npm install --package-lock-only
npm install
Я не добавлял 3-й шаг, но это единственное, что сработало для меня. Судя по всему, когда я пытался исправить аудит npm, я что-то напутал с мангустом. Спасибо за трюк.
Если вы удалите свой package-log.json
, вы должны переустановить его с помощью npm install --package-lock-only
. Иногда две отдельные установки npm создают блокировки пакетов, которые вызывают конфликты слияния в системах контроля версий.
Мой код работал нормально на одном ПК, но на другом я получил ту же ошибку. У меня есть бесплатный хостинг MongoDB от https://www.mongodb.com/.
Я исправил это, добавив свой текущий IP-адрес в Security - Network Access - IP Access List
на хостинг-сервере.
Сканирование скорости интернета или неспособность вашего сервера подключиться к удаленной базе данных также могут быть причиной ошибки.
У меня такая же проблема. В моем случае я сохранил оператор mongoose.connect в другом файле и забыл вызвать его при написании оператора require.
require(./services/mongoose);
Я сделал это в своем файле index.js и изменил его на это
require(./services/mongoose)();
Уже был кластер, коллекция, сделанная в моем атласе mongo db, все, что мне нужно было сделать, это очистить это и отправить еще один почтовый запрос, чтобы он заработал.
У меня была такая же проблема при использовании Mongoose 6. Я подключился к Mongoose в своем файле index.js следующим образом:
mongoose.connect(
process.env.MONGO_URL,
{ useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true },
() => {
console.info('Connected to MongoDB');
}
);
Я нашел следующую информацию для Mongoose 6 на их сайте:
useNewUrlParser, useUnifiedTopology, useFindAndModify и useCreateIndex больше не поддерживаются. Мангуст 6 всегда ведет себя так, как если бы useNewUrlParser, useUnifiedTopology и useCreateIndex являются истинными, а useFindAndModify — ложными. Пожалуйста, удалите эти параметры из вашего кода.
Когда я удалил опцию useCreateIndex: true
, проблема была решена.
Это сработало для меня. У вас есть идеи, почему useCreateIndex: true
вызывает проблемы?
Это вызвало проблемы, потому что это не поддерживаемая опция в Mongoose 6, и ее нельзя добавлять в опции (как говорит цитата в ответе), но у нас она была в опциях.
У меня была эта проблема сама, когда я пытался использовать свою базу данных, когда мой сервер был в ошибке, и мангуст создал огромную панель ошибок из 87 частей, которую мне пришлось просеивать, и когда я это сделал, я обнаружил, что параметры, которые я передал мангусту, были обесценивается. Поэтому, если вы можете прокрутить до места, где вы запускаете свой сервер, вы можете увидеть детали, говорящие вам удалить или добавить определенные параметры. Удаление дополнительных параметров решило мою проблему.
Убедитесь, что вы подключаетесь к MongoDB вверху своей функции (внутри файла) и выполняете (CRUD) операции после подключения к MongoDB Atlas.
Надеюсь, это имеет смысл. Я получаю сообщение об ошибке, потому что в своем файле я загружаю данные с другого сервера и вставляю в свою MongoDB после этих асинхронных операций, которые я подключаю к своему серверу MongoDB, поэтому я получаю сообщение об ошибке.
ПРАВИЛЬНО ↓
await mongoose.connect(MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
await parseAndLoadPlanetsData();
НЕПРАВИЛЬНО ↓
await parseAndLoadPlanetsData();
await mongoose.connect(MONGO_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
Я думаю, причина в том, что ваш IP-адрес не внесен в белый список для вашей базы данных. Проверьте это, если у вас есть такая проблема.
У меня это сработало после того, как я использовал этот код в моем файле app.js
:
mongoose.connect(process.env.DATABASE_URI, () => {
console.info("Mongo connected");
});
И удалил все четыре варианта мангуста ниже из моего кода:
{
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
}
Если вы пытаетесь запустить проект из другой сети или другого IP-адреса, убедитесь, что вы внесли свой IP-адрес в белый список в атласе mongoDB. Просто перейдите на вкладку «Сеть»> «Добавить IP-адрес».
Разрешить Network Access
отовсюду.
Обратите внимание, что это временное решение.
Эта ошибка пытается сказать, что она не может получить доступ к коллекции MongoDB. Это может быть в основном из-за этих 2:
Если вы импортируете строку подключения к базе данных из файла .env, убедитесь, что файл .env находится в корневой папке, в которой вы запускаете команду npm run
.
Я пробовал все решения здесь безрезультатно. Внезапно я понял, что файл .env находится в папке /server, которая на одну папку глубже, чем корневая папка моего проекта.
Убедитесь, что вы переместили файл .env
в корневую папку проекта!! Например, чтобы получить process.env.DB_CONNECT
.
Что делать, если соединение идеально