Atlas MongoDB connection - node.js

I am trying to connect to Atlas MongoDB with the following URI (provided by mongodb connection string )
module.exports = {
mongoURI:'mongodb+srv://<user>:<password>#cluster0-un6sk.mongodb.net/test?
retryWrites=true'
};
//connect to mongoose
mongoose
.connect(db)
.then( ()=>console.log('mongoDB connected'))
.catch(err => console.log(err));
I get the following error :
{ MongoNetworkError: connection 3 to cluster0-shard-00-00-un6sk.mongodb.net:27017 closed
at TLSSocket.<anonymous> (C:\Users\KARTIT Ismail\Desktop\devconnector\node_modules\mongodb-core\lib\connection\connection.js:352:9)
at Object.onceWrapper (events.js:273:13)
at TLSSocket.emit (events.js:182:13)
at _handle.close (net.js:606:12)
at TCP.done (_tls_wrap.js:386:7)
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {} }

Make sure you have whitelisted your IP in the Atlas Control panel.
You can enter 0.0.0.0, if you wish to allow access from any host.
Then you can have a connection string like below:
var connectionString= 'mongodb://<username>:<password>#<clustername>/<dbname>?ssl=true&replicaSet=<replica setname>&authSource=admin';
var db = mongoose.connect(connectionString).catch((error) => { console.log(error); });

Whitelist the IP address, the best option allows access from any host, I believe everyone had installed mongoose, if not then use this command
npm i mongoose
First copy your application connection string from mongodb.com -> clusters->connect->connect your application
Now chose driver Node.js and version latest, now copy connection string.
Now connection.js
const mongoose = require('mongoose');
const conStr = 'mongodb+srv://lord:<password>#cluster5-eeev8.mongodb.net/test?retryWrites=true&w=majority'
const DB = conStr.replace(
'<password>',
myPass
);
const DB = conStr.replace(
'test',
myDatabaseName
);
//remember mongoose.connect() return promise
mongoose
.connect(DB, {
usedNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
})
.then((con) => {
console.log(con.connection);
console.log('DB connection successful');
});

In order to connect to Atlas MongoDB you should configure IP whitelist. Go to MongoDB Atlas website, login. Then, from the Clusters view, select the Security tab, then IP Whitelist. You will see an IP address. Click "Edit" Button then "current IP address". Press OK. Then restart your server.
Useful link : https://docs.atlas.mongodb.com/security-whitelist/#add-whitelist-entries

What version of mongoose are you using? Versions of mongoose less than version 5.0.15 doesn't appear to support the mongodb+srv:// server url.
The other common issue, is white listed IP addresses.
Source:
Error at connecting to MongoDb Atlas Server

Just whitelist the IP from the Atlas UI no need to restart the application.

Related

MongoDB can be connected with MongoClient but not mongoose

So when I run my app in deployment, with the backend connecting to MongoDB using MongoClient as follow:
import { MongoClient } from 'mongodb'
const url = process.env.MONGODB_URI
MongoClient.connect(url, { useNewUrlParser: true, useUnifiedTopology: true },(err, db)=>{
console.log(url)
db.close()
})
everything works fine. But if I change it into
import mongoose from 'mongoose'
mongoose.Promise = global.Promise
mongoose.connect(url, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true })
mongoose.connection.on('error', () => {
throw new Error(`unable to connect to database: ${url}`)
})
it gives the following error:
webpack://HappyHourWeb/./server/server.js?:29
throw new Error(`unable to connect to database: ${_config_config__WEBPACK_IMPORTED_MODULE_0__["default"].mongoUri}`)
^
Error: unable to connect to database: my_database_url,
at NativeConnection.eval (webpack://HappyHourWeb/./server/server.js?:29:9)
at NativeConnection.emit (node:events:390:28)
at /Users/Hieudo/Documents/Project/HappyHourWeb/node_modules/mongoose/lib/connection.js:807:30
at processTicksAndRejections (node:internal/process/task_queues:78:11)
Any help is greatly appreciated!
According to various sources, including MongoDB Connection String URI reference, Mongoose connection docs (Ctrl+F and search for srv to jump to the right topic) and the most upvoted answer on this question on SO, you should handle standard URIs and DNS URIs differently.
Mongoose accepts a dbName option that is
[...]useful if you are unable to specify a default database in the connection string like with some mongodb+srv syntax connections.
The fact that the native MongoDB driver handles it automatically doesn't necessarily means that Mongoose will. Try separating the DB name from the URI and pass it as the second argument when connecting with Mongoose.
Also, that part of your code :
mongoose.connection.on('error', () => {
throw new Error(`unable to connect to database: ${url}`)
})
doesn't check for connection errors, it emits an event if an error is encountered after the initial connection has been made.
As Joe pointed out in the comments, you should handle both the initial connection errors AND errors that may come after it, either with the try/catch syntax or the .catch callback. More info in the docs.

Connection to MongoDB atlas using Node.js driver fails

at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) {
errno: 'ETIMEOUT',
code: 'ETIMEOUT',
syscall: 'queryTxt',
hostname: 'scheduly.1eln0.mongodb.net'
}
I’m facing the above connection Error while connecting with MongoDB Atlas. I’ve double-checked my username and password. I’ve whitelisted all the IP’s. I’m stuck in the middle of a project and cannot connect to the DB itself.
my connection strings are:
const mongoose = require("mongoose");
const mongodb = require("mongodb");
const uri = "mongodb+srv://ghulamghousdev:***********#scheduly.1eln0.mongodb.net/scheduly?retryWrites=true&w=majority
mongoose
.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connected");
})
.catch((err) => console.log(err));
The name of the Database on MongoDB atlas is scheduly.
Have you tried to add the ip of your VPS, host to the IP Whitelist of Network access?
You can see more details for that setting from here https://docs.atlas.mongodb.com/security-whitelist/

How to connect to postgresql database inside AWS EC2 instance using Node.js and Knex

I rented an EC2 instance of Ubuntu 16.xx on AWS and installed PostgreSQL on it. I created a database and table inside the PostgreSQL on EC2. Right now I am trying to connect to and get data from the database via a local Node.js project using knex.
I already enabled the inbound rule for port 5432 to IP from anywhere.
However, it returns error message as below:
Error: connect ECONNREFUSED 13.229.xxx.xxx:5432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1142:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '13.229.xxx.xxx',
port: 5432
}
How am I gonna fix it? Do I need to install and implement a reversed proxy? If so, how do I set it up? I know there is RDS on AWS, but I need to use EC2 to implement it.
Here are some of my codes:
This is the knex setting, I have pg installed. The connection to a local database is successful. But when I switch the host to whether a public IP/ private IP/ ec2-13-229-xxx-xxx.ap-southeast-1.compute.amazonaws.com. They all return the above error message.
development: {
client: 'postgresql',
connection: {
host: '13.229.xxx.xxx',
database: 'project2',
user: 'postgres',
password: 'postgres',
port: 5432,
},
pool: {
min: 2,
max: 10,
},
migrations: {
tableName: 'knex_migrations',
},
},
This is the Node.js code that I used to connect to the server. A very simple one, just to test the connection.
const express = require('express');
const hbs = require('hbs');
const app = express();
const knexConfig = require('./knexfile')['development'];
const knex = require('knex')(knexConfig);
let query = knex.select('*').from('users');
query
.then((data) => {
console.log(data);
})
.catch((err) => console.log(err));
This is my firewall setting which is turned off
Also, I paused my Kaspersky.
This is my pg_hba.conf file
And I am not sure where to add the permission of my personal IP.
This issue was related to the pg_hba.conf being restricted to localhost only.
Additionally the postgres.conf needed to have listen_addresses = '*'.
By whitelisting outside access, it was possible to access the database.
Additional support from this article.

How to use Fixie Socks (Heroku add-on) to connect to mongodb via mongoose

I have a node.js express api which I host on heroku. It connects to mongodb atlas via mongoose as follows
mongoose.connect(
`mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PWD}#${process.env.MONGO_HOST}/${process.env.MONGO_DEFAULT_DB}?retryWrites=true`, {
useNewUrlParser: true,
autoReconnect: true,
keepAlive: 300000,
connectTimeoutMS: 300000,
socketTimeoutMS: 300000
}
)
.then(result => {
console.log('Connected and listening to requests!');
app.listen(process.env.PORT || 3000);
.catch(err => console.log(err));
I want to use Atlas MongoDB Cloud's whitelist for the Heroku app, instead of opening access up to all. Heroku doesn't have fixed a IP address but makes them possible via an add-on called Fixie Socks, which acts as a proxy for outbound traffic.
How can I use this add-on to get the connection to work? The documentation gives several examples on how to connect to other services and databases, but there is no help on mongodb. All examples use the FIXIE_SOCKS_HOST which contains the SOCKSV5 proxy URL, user, pass and port, but I'm at a loss on how to use it in conjunction with the mongoose.connect method.
This question has been asked before, but when a different add-on was used (Fixie vs Fixie Socks), which didn't work.
I tried Fixie Socks but couldn't get it to work. But managed to successfully connect to Mongodb Atlas database with Quota Guard's static IP addresses following this documentation:
https://support.quotaguard.com/support/solutions/articles/12000066411-how-to-connect-to-mongodb-using-quotaguard
The trick is to use the use mongodb atlas' connection string without +srv command. To do that use an older driver version and it will provide you a connection string with 3 replica servers (each with 27017 port). Then create 3 tunnels at the Quota Guard dashboard.
Make sure you download the gqtunnel package and extract it your app's root folder. Then you just have to add the bin/qgtunnel to your procfile.
Example:
web: bin/qgtunnel your-application your arguments
I manage to connect from Heroku + node.js + Fixie SOCK add-on to MongoDB Atlas. A few parameters in MongoClient need to be set to direct MongoDB traffic to Fixie proxy. This is the snippet:
const {MongoClient, ServerApiVersion} = require('mongodb');
const username = process.env.USERNAME;
const password = process.env.PASSWORD;
const host = process.env.MONGO_DB_HOST;
const uri = "mongodb+srv://" + username + ":" + password + "#" + host + "/?retryWrites=true&w=majority";
const fixieData = process.env.FIXIE_SOCKS_HOST.split(new RegExp('[/(:\\/#/]+'));
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
serverApi: ServerApiVersion.v1,
proxyUsername: fixieData[0];
proxyPassword: fixieData[1];
proxyHost: fixieData[2];
proxyPort: fixieData[3];
});
Some of the MongoDB client connection options can be found here:
https://mongodb.github.io/node-mongodb-native/4.5/interfaces/ConnectionOptions.html
With modern versions of Mongoose, you can include the proxy-related driver options in the options object on mongoose.connect, and this works both with and without the +srv URL modifier.
const mongoose = require('mongoose');
const fixieData = process.env.FIXIE_SOCKS_HOST.split(new RegExp('[/(:\\/#/]+'));
mongoose.connect(process.env.DB_CONNECTION,
{
proxyUsername: fixieData[0],
proxyPassword: fixieData[1],
proxyHost: fixieData[2],
proxyPort: fixieData[3]
},
(error) => {
if (error){
console.log(error)
} else {
console.log('Connected to database')
}
}
)

Mongoose is not connecting MongoDB Atlas

This is the first time I use MongoDB Atlas to work with Mongo, and while trying to connect, that's the error I get:
Error: connect ECONNREFUSED 3.209.60.172:27017
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1054:14) {
name: 'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]: {}
}
This is my code:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
mongoose.connect('mongodb+srv://johnnybox:<password>#cluster0-cgxqx.mongodb.net/test?retryWrites=true&w=majority', {
useNewUrlParser: true
}).then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(require('./routes'));
app.listen(3331);
ps* I'm not missing my credentials
Already looked for a solution here but there's nothing similar to my problem.
My whitelist:
try this
mongoose
.connect(
'mongodb+srv://{my_user}:{mypass}#johnnybox-cgxqx.mongodb.net/johnnybox?retryWrites=true&w=majority',
{ useNewUrlParser: true }
)
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
Try adding your IP Address in the mongo atlas IP Whitelist.
Otherwise accept every connections if you don't need secure connection.
A new answer to the new error:
According to this answer, which had the same exact error, that is:
'MongoNetworkError',
errorLabels: [ 'TransientTransactionError' ],
[Symbol(mongoErrorContextSymbol)]:
Add your current IP to whiteList following "clusters/security/whitelist" in MongoDB website.
I'm sorry, I spent at least an hour to solve this. That's all I can do.
Old answer addressing the former error (he fixed this part, but still got a new error):
If you read the error log carefully it says:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block
That means you needed to add catch() to your mongoose connection:
mongoose.connect({some code}).then({some code}).catch(err => console.log(err))
I tried to run this code at home and it worked perfectly!
So it was something here in my office, after some testing, the problem was with the connection port that was locked.
Take a look:
Error: connect ECONNREFUSED 3.209.60.172:27017
Note that it connects to the port 27017
**The Ip is random, so it changes after every requisition.
After my Sd opened this port, everything worked properly!!
Thanks so much for your help guys!
For those of you who tried various URIs the only thing that got it working here is to Add you IP vs allow the access from anywhere. Hope that saves you some time.

Resources