Mongo DB not connecting to NodeJS after Heroku deployment - node.js

I've a MERN app (Mongo Express React Node) that works locally, and connects to my MongoDB database, getting data.
The React front-end works after I deploy it to Heroku, but Nodejs won't connect to MongoDB on Heroku.
The environment variables like MONGO_URI stored as Heroku config variables, works perfectly fine, yet it just won't connect to my MongoDB.
The Heroku logs shows the error message: DISCONNECTED FROM MONGO DB from my server.js file.
How can I solve this?
server.js file
const express = require("express");
const dotenv = require("dotenv");
const cookieParser = require("cookie-parser");
const mongoose = require("mongoose");
const cors = require("cors");
const path = require("path");
dotenv.config();
const authRouter = require("./routes/auth");
const blogRouter = require("./routes/blog");
const userRouter = require("./routes/user");
const app = express();
app.use(express.json());
app.use(cookieParser());
app.use(cors());
app.use("/api/auth", authRouter);
app.use("/api/user", userRouter);
app.use("/api/blog", blogRouter);
if(process.env.NODE_ENV === "production"){
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
const connect = () => {
mongoose
.connect(process.env.MONGO_URL,
{useNewUrlParser: true,
useUnifiedTopology: true,
useNewUrlParser: true})
.then(() => {
console.log("CONNECTED TO THE MONGO DB");
})
.catch((err) => {
console.log(err);
mongoose.disconnect(() => {
console.log("DISCONNECTED FROM MONGO DB");
});
})
};
app.listen(process.env.PORT || 8000, () => {
connect();
console.log("MONGO_URL", process.env.MONGO_URL);
console.log("PASSCODE", process.env.PASSCODE);
console.log(`LISTENING ON PORT ${process.env.PORT}`);
})

Your environment variable to connect to MongoDB database has to be MONGO_URI, not MONGO_URL.
Otherwise it won't work.

Related

How find endpoints of my heroku deployed nodejs app?

Below you can see my localhost nodejs api endpoint and its successfullyworking.
http://localhost:3000/api/user/login/
But after I deployed app in Heroku I cannot call that endpoint.
After deployed in the heroku I tried with this url
https://employee-management-app-001.herokuapp.com/api/user/login
Below you can see my server file
const express = require('express')
const app = express()
const mongoose = require('mongoose')
const port = process.env.PORT || 3000;
const uri = 'mongodb+srv://user1:1234#cluster0.pkiw6x0.mongodb.net/comp3123_assignment1'
//const jwt =require('jsonwebtoken');
var cors = require('cors')
app.use(cors())
mongoose.connect(uri, {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log("Successfully connected to the database mongoDB Atlas Server");
}).catch(err => {
console.log('Could not connect to the database.', err);
process.exit();
});
app.use(express.json())
const usersRouter = require('./routes/users')
app.use('/api/user',usersRouter)
const employeesRouter = require('./routes/employees')
app.use('/api/emp',employeesRouter)
mongoose.connect(uri)
app.listen(port,()=> console.log("Server Started on Port "+port))
Can anyone helop me to solve thiss issue?

heroku connecting to mongodb atlas only when node conected and running on vsCode

I create a web site with MERN stack and deploy it with heroku. the DB connected to mongodb atlas. work great locali but when i try to connect the DB with heroku its working only when my backend on vsCode connected to the DB.
the error notes is:
*Failed to load resource: net::ERR_CONNECTION_REFUSED
*Uncaught (in promise) Error: Network Error
at e.exports (createError.js:16:15)
at XMLHttpRequest.g.onerror (xhr.js:117:14)
this is my code:
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const morgan = require("morgan");
const cors = require("cors");
const usersRouter = require("./routes/usersRout");
const authRouter = require("./routes/auth");
const carsRouter = require("./routes/carsRout");
const bizRouter = require("./routes/bizRout");
mongoose
.connect(
process.env.MONGODB_URI ||
"mongodb+srv://reutudler:eJ53Guyvm7ySeMra#notodb.s9aba.mongodb.net/notodb?retryWrites=true&w=majority"
)
.then(() => {
console.log("connected to mongo");
})
.catch((err) => {
console.log("faild to connect to mongo server", err);
});
app.use(cors());
app.use(morgan("dev"));
app.use(express.json());
if (process.env.NODE_ENV === "production") {
app.use(express.static("noto-front/build"));
}
app.use("/api/users", usersRouter);
app.use("/api/auth", authRouter);
app.use("/api/cars", carsRouter);
app.use("/api/biz", bizRouter);
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`connected on port ${PORT}`);
});
my config vars on heroku:
MONGODB_URI - mongodb+srv://reutudler:eJ53Guyvm7ySeMra#notodb.s9aba.mongodb.net/notodb?retryWrites=true&w=majority
NODE_ENV - production
what am i doing wrong?

Express Router unable to route to another folder

I am trying to create a Node JS app with mongoDB. from main app.js I am trying to redirect to another folder named "services". Here is my folder structure -
Here is my app.js -
const express = require('express')
const mongoose = require('mongoose')
const dotenv = require('dotenv')
const cors = require('cors')
const bodyParser = require('body-parser')
const app = express()
const users = require('./userSchema')
const services = require('./services/index')
app.use('/services', express.static('/services'))
app.use(express.static('/'));
app.use(cors())
dotenv.config()
const port = 3000
mongoose.connect(process.env.DB_CONNECT,
{
useUnifiedTopology: true,
useNewUrlParser: true,
useFindAndModify: false
})
.then(() => console.log('Connected to mongoDB'))
.catch(err => console.error('Could not connect to MongoDB..', err))
const jsonParser = bodyParser.json()
app.get('/allName', async (req, res) => {
let data = await users.find()
res.status(200).send(data)
})
app.listen(port, () => console.log(`Demo app listening on port ${port}!`))
Here is my index.js file inside services folder -
var express = require('express')
var router = express.Router()
router.get('/', function (req, res) {
res.send('Birds home page')
})
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
While running http://localhost:3000/allName , it is working fine. But if i try to run http://localhost:3000/services, it is throwing Cannot GET /services. I am not able to fix this.
How to redirect to index.js from app.js when users trigger http://localhost:3000/services?
change
app.use('/services', express.static('/services'))
into
app.use('/services', services);
express.static is used to serve static files, looks like you wish to use a router and not return static files. This is why the server does not respond as you like
Yes, because you haven't properly added the reference of the service routes.
Remove express.static from the reference because you already have imported the service routes in a variable then just use it and it will work as expected.
Just a note. Express.static is used to load/use the static files like css or images or something like that.
Check the code below.
const express = require('express')
const mongoose = require('mongoose')
const dotenv = require('dotenv')
const cors = require('cors')
const bodyParser = require('body-parser')
const app = express()
const users = require('./userSchema')
const services = require('./services/index')
**app.use('/services', services)** // change this into your code.
app.use(express.static('/'));
app.use(cors())
dotenv.config()
const port = 3000
mongoose.connect(process.env.DB_CONNECT,
{
useUnifiedTopology: true,
useNewUrlParser: true,
useFindAndModify: false
})
.then(() => console.log('Connected to mongoDB'))
.catch(err => console.error('Could not connect to MongoDB..', err))
const jsonParser = bodyParser.json()
app.get('/allName', async (req, res) => {
let data = await users.find()
res.status(200).send(data)
})
app.listen(port, () => console.log(`Demo app listening on port ${port}!`))

Error while deploying react js and node app to aws

I want to deploy my app to aws, i search and i found alot of tutorials i try each one and i get this error on the browser:
Cannot GET /
I figure maybe that my problem is from my nodeJS server code.
This is my server.js code hope you guys can help me thanks.
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const path = require('path');
const cors = require('cors');
//Api routes
const users = require('./routes/api/usuario');
const alumno = require('./routes/api/alumno');
const personal = require('./routes/api/personal');
const zonas = require('./routes/api/zonas');
const sepomex = require('./routes/api/sepomex');
const app = express();
app.use(cors());
//Body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//Db config
const db = process.env.NODE_ENV === "production" ? require('./config/keys').mongoURIProd : require('./config/keys').mongoURIDev;
//connect to mongo DB
mongoose
.connect(db, { useNewUrlParser: true })
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
//passport middleware
app.use(passport.initialize());
//passport config
require('./config/passport')(passport);
//Use routes
app.use('/api/usuario', users);
app.use('/api/alumno', alumno);
app.use('/api/personal', personal);
app.use('/api/zonas', zonas);
app.use('/api/sepomex', sepomex);
//serve static assets to production
if (process.env.NODE_ENV === "production") {
//static folder
app.use(express.static("client/build"));
app.get('/*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
})
}
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
I have deployed my app on heroku and works fine.
If you are deploying to EC2 instance then you need to specify IP address in app.listen to be 0.0.0.0, by default it is set to localhost which is not what you want if you want the app to be reachable from outside.
You should change your code to
app.listen(port, '0.0.0.0', () => {
console.log(`Server running on port ${port}`);
});

Vue + Express app on heroku not using the SPA in server/public folder

My app is running on heroku and the routes send me JSON files, but what I need is to use the SPA that is in my ./server/public folder as index.html.
When I open the heroku app it send me the JSON file that is sent from the "/" route, but I need it to use the Vue SPA, because of what I did in my front-end client if for some reason you go to a route that doesn't exists it does redirect me to my "/forum" route with the front-end client, but any other route that exists will not work, it will keep sending the JSON of that route.
app/server.js
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const expressValidator = require("express-validator");
const flash = require('connect-flash');
const mongoose = require('mongoose');
const cors = require("cors");
const config = require("./config/database");
if(process.env.NODE_ENV !== "production") require('dotenv').config();
mongoose.connect(config.database, { useNewUrlParser: true, useFindAndModify: false });
let db = mongoose.connection;
db.once("open", () => {
console.log("Connected to MongoDB Atlas");
});
db.on("error", (err) => {
console.log(err);
});
const app = express();
//Body-parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use(expressValidator());
app.use(flash());
app.use(cors());
require("./passport")
//Routes
const home = require("./routes/home.js");
const forum = require('./routes/forum.js');
const ranking = require('./routes/ranking.js');
const profile = require('./routes/profile.js');
// Routing
app.use("/", home);
app.use("/forum", forum);
app.use("/profile", profile);
app.use("/ranking", ranking);
// Handle production build
if (process.env.NODE_ENV === "production") {
app.use(express.static(__dirname + '/public/'));
app.get(/.*/, (req, res) => { res.sendFile(__dirname + '/public/index.html') });
}
// PORT
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server listening on port ${port}`)
});
If you are splitting the frontend and the backend with Vue and Express, you should probably build and host the Vue part statically and then have your Express running on Heroku.
Here is a guide on how to deploy your express app, and then you build and deploy your static Vue page, here are the docs for deploying Vue.

Resources