Mongoose error when deploying on Heroku nodejs - node.js

I have completed a project and trying to deploy on heroku. I am using Reactjs frontend and express Nodejs with mongoose and mongodb in the Backend. It works on localhost but when I run Build it and try to deploy it on heroku it gives an application error.
Here is my backend connection code:
require('dotenv').config();
const express = require('express')
const session = require("express-session")
const bodyParser = require('body-parser')
const cors = require('cors')
const zomatoRoutes = require('./Routes/zomato')
const paymentRoutes = require('./Routes/payments')
const mongoose = require('mongoose')
const passport = require("passport")
const MongoStore = require('connect-mongo');
const uri = process.env.MONGO_URI || 'mongodb://localhost/zomato';
console.log(uri,'this is the mongo Atlas uri if connected using that !!!')
const options = {
useNewUrlParser: true,
useUnifiedTopology: true,
dbName:'zomato1'
}
const connectDB = async () => {
await mongoose.connect(uri, options ).then(() => {
console.log('mongo connected')
}).catch( e => console.log(e))
}
connectDB().then(() => {
app.listen( process.env.PORT ||5252 , () => {
console.log("express app is up and running on port 5252");
})
})
I also have mongo session store the mongoose session when user logs in
app.use(session({
secret: "this is unambigous secret",
resave: false,
saveUninitialized: false,
cookie: { maxAge: 24*60*60*1000 },
store : MongoStore.create({
client: mongoose.connection.getClient(),
dbName:'zomato1',
ttl: 14 * 24 * 60 * 60
})
}));
app.use(passport.initialize());
app.use(passport.session());
It gives me MongoNotConnectedError: MongoClient must be connected to perform this operation error when I try to deploy using
git push heroku master:main
full error tail :
mongodb+srv://vishal_torne_22:********#db-first-hernode.zu6btrs.mongodb.net/<DBNamecomeshere>?retryWrites=true&w=majority this is the mongo Atlas uri if connected using that !!!
2022-07-31T11:19:34.581869+00:00 app[web.1]: /app/node_modules/mongodb/lib/utils.js:367
2022-07-31T11:19:34.581876+00:00 app[web.1]: throw new error_1.MongoNotConnectedError('MongoClient must be connected to perform this operation');
2022-07-31T11:19:34.581877+00:00 app[web.1]: ^
2022-07-31T11:19:34.581877+00:00 app[web.1]:
2022-07-31T11:19:34.581878+00:00 app[web.1]: MongoNotConnectedError: MongoClient must be connected to perform this operation
2022-07-31T11:19:34.581878+00:00 app[web.1]: at getTopology (/app/node_modules/mongodb/lib/utils.js:367:11)
2022-07-31T11:19:34.581881+00:00 app[web.1]: at Collection.createIndex (/app/node_modules/mongodb/lib/collection.js:258:82)
2022-07-31T11:19:34.581881+00:00 app[web.1]: at MongoStore.setAutoRemove (/app/node_modules/connect-mongo/build/main/lib/MongoStore.js:147:35)
2022-07-31T11:19:34.581881+00:00 app[web.1]: at /app/node_modules/connect-mongo/build/main/lib/MongoStore.js:128:24
2022-07-31T11:19:34.581882+00:00 app[web.1]: at processTicksAndRejections (node:internal/process/task_queues:96:5)
2022-07-31T11:19:34.581882+00:00 app[web.1]:
2022-07-31T11:19:34.581882+00:00 app[web.1]: Node.js v17.9.1
2022-07-31T11:19:34.703486+00:00 heroku[web.1]: Process exited with status 1
2022-07-31T11:19:34.791551+00:00 heroku[web.1]: State changed from starting to crashed
I am using Mongoose to connect the Mongodb, It works on localhost without heroku but when I deploy it using heroku, It asks me to use MongoClient. Is it a requirement to use mongoClient on Heroku 20 stack, I also get warning to upgrade to new Heroku version, I tried to upgrade heroku using npm upgrade heroku to the specifed version it shows successful but again rolls back to heroku 20 stack.
here's what I tried but researching the previous answers :
I added on my mongodb atlas the whitelist 0.0.0.0/0 (includes you current IP address)
I tried to make the mongoose code async so that it connect firsts the database then app listens to the port.
changed the engine version so that it supports latest node and npm version on Heroku like:
{
"version": "1.0.0",
"engines": {
"node": "17.x",
"npm":"8.x"
}
}
Is it a requirement to use MongoClient on heroku 20 stack ? as the Error shows... and why it is showing error on Mongoose.connect()
Thanks in advance..!

As you say it runs fine in your local environment, the issue may be fixed by adding process.env.MONGO_URL to the config vars of your application, as the issue may originate when Heroku tries to connect to your MongoDB, but does not achieve this connection due to an invalid url that is stored in an env variable on your local device.

Related

Connect to MongoDB cluster

Hi I am trying to connect MongoDB and I got an error. I worked on connecting DB by "connect with the MongoDB shell", but this time I want to connect with the "connect your application" option.
When I hit mongosh in the embedded terminal in my mac, below was returned.
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.2.2
Using MongoDB: 5.0.6
Using Mongosh: 1.2.2
...
...
...
test>
Because I am new to MongoDB, I don't even know if it's correctly working or not. Also, I wanna connect by coding. That's why I am asking here. Below are some parts of my code in an app I have been working on.
Thanks for your time for dedication here. So appreciate it.
// this is db.js file in a config folder.
const mongoose = require('mongoose')
// It must be a promise function to connect db
const connectDB = async () => {
try {
console.log(`try`)
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
dbName: 'expense2'
});
console.log(`MongoDB Connected: ${conn.connection.host}`.syan.underline.bold)
} catch (error) {
console.log(`Error: ${error.message}`.red)
process.exit(1);
}
}
module.exports = connectDB;
/*
Here is the error happened
Error: Could not connect to any servers in your MongoDB Atlas cluster. One common reason is that you're trying to access the database from an IP that isn't whitelisted. Make sure your current IP address is on your Atlas cluster's IP whitelist: https://docs.atlas.mongodb.com/security-whitelist/
[nodemon] app crashed - waiting for file changes before starting...
*/
config.env in the config folder as well.
NODE_ENV = development;
PORT=5000
MONGO_URI=mongodb+srv://mongo:mongo#cluster0.8tjjn.mongodb.net/expense2?retryWrites=true&w=majority
// server.js file
const express = require('express');
const dotenv = require('dotenv');
const colors = require('colors');
const morgan = require('colors');
const connectDB = require('./config/db')
dotenv.config({ path: "./config/config.env" })
connectDB();
const app = express();
const transactionsRouter = require('./routes/transactions')
app.use('/transactions', transactionsRouter)
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`server running in ${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold));

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

How to deploy Node Media Server app on heroku

I am trying to deploy a NodeJS live streaming server which works on heroku built on rtmp server using node-media-server and socket.io. I am facing issue in starting the node-media-server since it needs 2 ports to run as per config format:
const NodeMediaServer = require('node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
allow_origin: '*'
}
};
var nms = new NodeMediaServer(config)
nms.run();
I've tried deploying app on new heroku app by following official guide. Since Heroku provides only one port per dyno, it gives me these logs on my heroku app dashboard:
2020-04-07T23:08:24.289041+00:00 app[web.1]: 4/7/2020 23:08:24 23 [ERROR] Node Media Trans Server startup failed. ffmpeg:/usr/local/bin/ffmpeg cannot be executed.
2020-04-07T23:08:24.290753+00:00 app[web.1]: (node:23) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
2020-04-07T23:08:24.291397+00:00 app[web.1]: listening on port 19586
2020-04-07T23:08:24.292059+00:00 app[web.1]: 4/7/2020 23:08:24 23 [ERROR] Node Media Rtmp Server Error: listen EADDRINUSE: address already in use :::19586
2020-04-07T23:08:24.292694+00:00 app[web.1]: 4/7/2020 23:08:24 23 [ERROR] Node Media Http Server Error: listen EADDRINUSE: address already in use :::19586
2020-04-07T23:08:24.293383+00:00 app[web.1]: 4/7/2020 23:08:24 23 [ERROR] Node Media WebSocket Server Error: listen EADDRINUSE: address already in use :::19586
2020-04-07T23:08:24.682440+00:00 heroku[web.1]: State changed from starting to up
2020-04-07T23:08:24.693405+00:00 app[web.1]: Connected to the database
I need to know how I can deploy my app on heroku (or any other alternative) to make it available in production mode. My server works fine on my MacBook Pro.
Here's my code:
const { NodeMediaServer } = require('node-media-server');
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const http = require('http');
const fs = require('fs');
const bodyParser = require('body-parser');
const path = require('path');
const process = require('process')
const port = process.env.PORT||5000
const port2 = process.env.PORT||8000
const port3 = process.env.PORT||8001
const server = http.createServer(app);
const io = require('socket.io').listen(server);
require('./app/controllers/socketIO')(io);
mongoose.Promise = global.Promise;
global.appRoot = path.resolve(__dirname);
mongoose.connect(
"mongodb://databasecredentials",
{ useNewUrlParser: true },
err => {
if (err) {
console.log(err);
} else {
console.log('Connected to the database');
}
}
);
app.use(
bodyParser.urlencoded({
extended: true
})
);
app.use(bodyParser.json());
app.set('socketio', io);
app.set('server', server);
app.use(express.static(`${__dirname}/public`));
server.listen(port, err => {
if (err) {
console.log(err);
} else {
console.log(`listening on port ${port}`);
}
});
const nodeMediaServerConfig = {
rtmp: {
port: port2,
chunk_size: 60000,
gop_cache: true,
ping: 60,
ping_timeout: 30
},
http: {
port: port3,
mediaroot: './media',
allow_origin: '*'
},
trans: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'live',
ac: 'aac',
mp4: true,
mp4Flags: '[movflags=faststart]'
}
]
}
};
var nms = new NodeMediaServer(nodeMediaServerConfig);
nms.run();
I'm not very familiar with Heroku, but in the first line of the logs it states:
[ERROR] Node Media Trans Server startup failed. ffmpeg:/usr/local/bin/ffmpeg cannot be executed.
you need to install ffmpeg on the machine running the code. This is the first step to get your server starting (this might not fix all the problems you're having but this is the first thing you need to start with).
I'm trying to do something similar using GCP. In order to get it to run, I created a package.json file and set the start script to apt install --fix-missing --assume-yes ffmpeg && node app.js as a temporary workaround:
{
"name": "app-service-hello-world",
"description": "Simple Hello World Node.js sample for Azure App Service",
"version": "0.0.1",
"private": true,
"license": "MIT",
"author": "Microsoft",
"scripts": {
"start": "apt install --fix-missing --assume-yes ffmpeg && node app.js"
},
"dependencies": {
"node-media-server": "^2.1.9"
}
}
This might help you adding ffmpeg correctly to your Heroku environment: Install FFMPEG on Heroku

Couldn't resolve the error coming for mongodb atlas after deploying it on heroku?

In locally the application works perfectly but when i deployed it on heroku it showing errors on heroku logs. Also data wasn't added in mongoDb database. Actually in the application i used google-oauth login so in locally it works perfectly but not in heroku. I've also whitelisted my ip on mongodb atlas but still can't figure out why this error getting.
Anybody help me plz.....
Here is my prod.js file
module.exports = {
googleClientID: process.env.GOOGLE_CLIENT_ID,
googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
mongoURI: process.env.MONGO_URI,
cookieKey: process.env.COOKIE_KEY
}
Here is my keys.js file
// Keys.js - figure out what credentials should return
if (process.env.NODE_ENV === "production") {
// So we are in prodution - return the prod set of keys
module.exports = require('./prod');
} else {
// We are developement - return the dev keys
module.exports = require('./dev');
}
Here is my index.js file
const express = require('express');
const mongoose = require('mongoose');
const passport = require('passport');
const cookieSession = require('cookie-session');
const keys = require('./config/keys');
require('./models/User');
require('./services/passport');
const app = express();
//Middleware
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [keys.cookieKey]
})
);
app.use(passport.initialize());
app.use(passport.session());
// mongoDb Connection
mongoose.connect(keys.mongoURI, {
useNewUrlParser: true
}).then(() => console.log('MongoDb Connect successfully'))
.catch(err => console.log(err));
// actual routes
require('./routes/authRoutes')(app);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server is running in ${PORT}`));
Actually i getting two different errors first was this
2019-09-02T06:28:59.760121+00:00 app[web.1]: Warning: connect.session() MemoryStore is not
2019-09-02T06:28:59.760149+00:00 app[web.1]: designed for a production environment, as it will leak
2019-09-02T06:28:59.760151+00:00 app[web.1]: memory, and will not scale past a single process.
2019-09-02T06:28:59.763577+00:00 app[web.1]:
2019-09-02T06:28:59.763581+00:00 app[web.1]: /app/node_modules/mongoose/lib/connection.js:519
2019-09-02T06:28:59.763583+00:00 app[web.1]: throw new MongooseError('The `uri` parameter to `openUri()` must be a ' +
2019-09-02T06:28:59.763585+00:00 app[web.1]: ^
2019-09-02T06:28:59.763838+00:00 app[web.1]: MongooseError: The `uri` parameter to `openUri()` must be a string, got "undefined". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.
2019-09-02T06:28:59.763842+00:00 app[web.1]: at new MongooseError (/app/node_modules/mongoose/lib/error/mongooseError.js:10:11)
2019-09-02T06:28:59.763844+00:00 app[web.1]: at NativeConnection.Connection.openUri (/app/node_modules/mongoose/lib/connection.js:519:11)
2019-09-02T06:28:59.763846+00:00 app[web.1]: at Mongoose.connect (/app/node_modules/mongoose/lib/index.js:321:15)
2019-09-02T06:28:59.763848+00:00 app[web.1]: at Object.<anonymous> (/app/index.js:24:10)
2019-09-02T06:28:59.763850+00:00 app[web.1]: at Module._compile (internal/modules/cjs/loader.js:701:30)
2019-09-02T06:28:59.763852+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
2019-09-02T06:28:59.763854+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:600:32)
And the second one is this
2019-09-02T08:49:22.115492+00:00 app[web.1]: { MongoNetworkError: failed to connect to server [productionproj-shard-00-00-qfouv.mongodb.net:27017] on first connect [MongoNetworkError: connection 5 to productionproj-shard-00-00-qfouv.mongodb.net:27017 closed]
So on...... as same as above
Here is my mongodb production url i've been added on heroku config vars
mongodb+srv://nansProdDeploy:nansProdDeploy#productionproj-qfouv.mongodb.net/test?retryWrites=true&w=majority
It's all about whitelisting the correct ip address. When we put our application on heroku we must whitelist the ip by clicking [ Allow Access From Anywhere ] button and then click ok your ip will be 0.0.0.0/0 this ip will allow to access your deployed heroku application. When you are using your application locally at that point of you have to choose [ Add Current Ip Address ] to access your application locally

Node/express application failing to connect to Mongodb Atlas using mongoose

I have a node/express application that I am trying to connect to Mongodb Atlas using mongoose.
All of my code is identical to a previous app that I had connect to Atlas (which worked fine). When I run it on my work machine (Windows 10) everything works as expected. However, when I run it on my MacBook Pro (Mojave), the express app runs but the mongoose connection to Atlas throws the following error:
{ Error: queryTxt EBADNAME development-zv5hp.mongodb.net
at QueryReqWrap.onresolve [as oncomplete] (dns.js:196:19)
errno: 'EBADNAME',
code: 'EBADNAME',
syscall: 'queryTxt',
hostname: 'development-zv5hp.mongodb.net' }
server.js
const express = require('express');
const mongoose = require('mongoose');
const app = express();
mongoose
.connect(
'mongodb+srv://client:<PASSWORD>#development-zv5hp.mongodb.net/shop',
{ useNewUrlParser: true }
)
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
What might be causing this issue?
I have checked the Atlas user and password and have whitelisted my IP (in fact whitelisted all IPs)
Using:
node v10.15.3
express v4.16.4
mongoose v5.5.1
Using Google's DNS server 8.8.8.8 and 8.8.4.4 can resolve this issue
please add autoIndex: false its working for me
mongoose
.connect(
'mongodb+srv://client:<PASSWORD>#development-zv5hp.mongodb.net/shop',
{autoIndex: false, useNewUrlParser: true }
This error is caused because the URI 'mongodb+srv://client:<PASSWORD>#development-zv5hp.mongodb.net/shop' that was passed to connect was unable to be resolved. Your DNS server does not know it and thus cannot resolve an IP. Hence ebadname.
change this like Addison mentioned

Resources