Unable to connect to mongodb database with my heroku app? - node.js

I am unable to connect my Node.js app deployed to Heroku with a MongoDB database. It works fine on localhost, but not on Heroku.
In my logs, I see this:
MongoNetworkError: failed to connect to server [authproject-shard-00-01-ybey8.mongodb.net:27017] on first connect [MongoNetworkError: connection 4 to authproject-shard-00-01-ybey8.mongodb.net:27017 closed]
custom-environment-variables.json:
{
"db": "Auth_db"
}
default.json:
{
"db": "mongodb://localhost/user"
}
db.js:
const db = config.get("db");
mongoose
.connect(db)
.then(() => console.log("connected to mongodb.."))
.catch(err => console.error("could not connect to mongodb", err));
};

You need to configure an environment variable in your Heroku application.
Run in console:
heroku config:set MONGODB_URI='urlOfYourMongoDatabase'
Then upgrade your db.js like this:
const mongoose = require('mongoose')
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/TodoApp', { useNewUrlParser: true })
.then(connect => console.log('connected to mongodb..'))
.catch(e => console.log('could not connect to mongodb', e))
module.exports = {mongoose}
Good luck!

Allow heroku ip access in mongodb by setting allow access from anywhere in network acess in mongodb.
this works,
but not sure how secured is it by allowing access from anywhere.

In 2021, navigate to your app in Heroku. Click on "Settings" menu. Once it opens expand "Config Vars" by clicking on it. Fill KEY and VALUE fields as it as in your .env file. Suppose you have DB_HOST=url/of/your/mongodb in your .env. The KEY will be DB_HOST and VALUE will be url/of/your/mongodb. Now click on ADD button. You are good to go.

Related

Can't connect to MongoDB through heroku but works on localhost

Trying to push my simple notes app to heroku but when launched on heroku mongoDB gives me this error
Could not connect to any servers in your MongoDB Atlas cluster.
My backend works perfectly fine while my app is running locally and I have whitelisted all IPs in mongoDB and added MONGODB_URI as a local var in heroku so I'm unsure what is wrong at this point.
Here is my connection.
const mongoose = require('mongoose')
const url = process.env.MONGODB_URI
console.log('Connecting to..', url)
mongoose.connect(url, { useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false, useCreateIndex: true })
.then(result => {
console.log('Connected to MongoDB')
})
.catch((error) => {
console.log(`Error connecting to MongoDB: `, error.message)
})
Fixed the problem by deleting my whitelist in mongoDB Atlas and then adding it back, my server connected on heroku after that.

heroku DATABASE_URL is undefined in nodejs app

Heroku site states that the DATABASE_URL is setup automatically for you. I used the command
heroku config
to confirm that the DATABASE_URL is indeed set.
However when I use the pg package command
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: true,
});
and do a console.log(process.env.DATABASE_URL), the variable reads as undefined.
The other errors that I am getting are:
UnhandledPromiseRejectionWarning: Error: The server does not support SSL connections
The complete code is:
const express = require('express');
require('dotenv').config();
const { Client } = require('pg');
const app = express();
console.log(process.env.DATABASE_URL);
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: true,
});
client.connect();
client.query('SELECT * FROM customers;', (err, res) => {
if (err) throw err;
for (let row of res.rows) {
console.log(JSON.stringify(row));
}
client.end();
});
app.get('/', (req, res) => {
res.send('Hello World')
});
app.listen(4000, () => {
console.log(`Server started on port`);
});
The code works when I use my local postgresql database, but when I try to connect to Heroku's postgres database, the above errors occur. Any suggestions?
Seems you're not crazy... This isn't working for me either, so I dug in, and it just seems... broken.
https://stackoverflow.com/a/19341505/4526479
I see DATABASE_URL defined in the heroku config vars section in the online heroku dashboard. But it's just undefined in the app.
It looks like you're running into issues connecting to the Heroku Postgres database when you run the project locally.
The DATABASE_URL environment variable specified in heroku config exists only on the Heroku server and you don't have the environment variable set locally.
Create a .env file and include your connection string like so
DATABASE_URL=...
Here you can include the connection string for the database hosted on Heroku, or your local Postgres database server. Just make sure SSL is configured correctly

Postgres server is not responding to a nodejs request

I have access to a remote postgres DB from pgAdmin4 and I also could access from nodejs using a Mac. Right now I'm using the same code to access the DB in Windows. The code for my connection is the following:
const { Client } = require('pg'); //Importing the Postgres package
const hosts= require('../hosts'); //Using the file containig all hosts
const connectionData = { //Begin creating the connection settings object
host: hosts.DBHost, //DB host
port: hosts.DBPort, //DB hosts port
database: hosts.DB, //DB
user: hosts.DBUser, //DB user
password: hosts.DBPassword, //DB user password
}
My test is the following:
var client = new Client(connectionData); //New client instance using the above connection settings
client.connect(); //Open the connection to the database()
sql = "select * from myTable";
client.query(sql)
.then(response => {
console.log ({"data": response}); //This isn't shown
})
.catch(err => {
console.log({"error": err}); //This isn't shown neither
})
No error, no exception, the DB server doesn't respond!
Why isn't the server responding?
I suspect that you have the same problem like in this other post. Since it is not a 100% duplicate I will post this again:
There is a known issue in the pg module and NodeJS 14.
The proposed solution is to make sure you have pg>=8.0.3 installed.
This can be done by updating pg in the dependencies.
Also make sure, that any other library depending on the pg module, is also up to date and has the latest pg version.
If this is not possible for any reason - using Node 12 should also work.

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')
}
}
)

Atlas MongoDB connection

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.

Resources