I am a beginner to MERN stack and I deployed my nodejs app to heroku but the app is unable to connect to mongodb atlas and data from the database does not load when I give the mongodb uri via an environment variable.It works fine when I directly give the uri via a variable.Also when run locally,the app connects to atlas without any problem using environment variable.Any idea why its not working on heroku and how to fix it?
server.js
const express = require('express'); //nodejs framework for creating web apps
const cors = require('cors');
const mongoose = require('mongoose');
const path = require('path');
require('dotenv').config(); //for setting environment variables on server
const app = express(); //creating the app
//Serve static assets if in production
if(process.env.NODE_ENV ==='production'){
//Set 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.use(cors()); //for cross origin resource sharing ie.cross domain requests
app.use(express.json()); //for handling json data
const uri = process.env.ATLAS_URI;
//its works fine when I give it as below
//const uri="mongodb+srv://jose:<password>#exercisecluster-rmqkg.gcp.mongodb.net/test?retryWrites=true&w=majority"
mongoose.connect(uri,{ useNewUrlParser: true, useCreateIndex: true ,useUnifiedTopology: true });
const connection = mongoose.connection;
connection.once('open',() => {
console.log('Database connection established successfully');
})
const exercisesRouter = require('./routes/exercises');
const usersRouter = require('./routes/users');
//executes the files in the second argument when user enters the url 'rooturl/firstargument'
app.use('/exercises',exercisesRouter);
app.use('/users',usersRouter);
app.listen(port,() => {
console.log(`Server is running on port:${port}`);
});
In your heroku project you need to setup an env variable ATLAS_URI and enter the value for your mongodb uri.
To do so go to the settings tab in your heroku app, then click on reveal config vars, and then enter the key and value for your mongo uri.
Hope this helps
Related
I recently tried to deploy json-server to my interserver's shared hosting plan via cPanel.
I uploaded the app and configured a Node.js app and I'm able to access the endpoint via 'https://soltonbaev.com/json-server/api/contacts' however the jsonServer.rewriter() is not rewriting the "/api/" route to the "/".
In addition I cannot access the individual object via it's id, like for instance "https://soltonbaev.com/json-server/api/contacts/1". Server returns 404.
So clearly, JSON server is not picking up the routes when it is supposed to.
Here is the content of my server.js file
require('dotenv').config();
const jsonServer = require('json-server');
const cors = require('cors');
const server = jsonServer.create();
const router = jsonServer.router('database.json');
const middlewares = jsonServer.defaults();
const port = process.env.PORT || 3000;
server.use(
jsonServer.rewriter({
'/api/*': '/$1',
})
);
server.use(cors({origin: process.env.REMOTE_CLIENT_APP, credentials: true}));
server.use(middlewares);
server.use(router);
server.listen(port, () => {
console.log(
`🚀 JSON Server is running on ${process.env.REMOTE_CLIENT_APP}:${port}}`
);
});
I trying to open a local website on my local network that I can access from every devices in my network.
I use React as frontend, Nodejs as backend and mongodb is my database(Locally).
On the computer where everything is running I can enter the site through my address on the local network and see the data that is in the database, but as soon as I enter the site through another computer that is on the same network I see the site but not the data from the database.
How i can fix this ?
I use this code for the node js server and run node server in terminal:
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const ip = require('ip');
const app = express();
require('dotenv').config();
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri);
const connection = mongoose.connection;
connection.once('open', () => {
console.log('MongoDB database connection established successfully');
});
const exercisesRouter = require('./routes/exercises');
const usersRouter = require('./routes/users');
app.use('/exercises', exercisesRouter);
app.use('/users', usersRouter);
app.use(express.static('../build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve('../build/index.html'));
});
const PORT = process.env.PORT || 3000;
console.log('server started on port:', PORT, ip.address());
app.listen(PORT,"0.0.0.0");
First thing is to specify the react HOST. If you're using create-react-app, Simply run HOST=your_ip npm run start.
To get this your_ip, run ifconfig on unix systems, and you'll find the IP for the your PC on the LAN you're connected to.
For the nodejs side, you might need to try something like
server.listen(80, 'current_local_ip');.
I am new to fullstack development and I want to deploy a project that will be used on the same network by different users. I have used angular for the front-end and node/express and MySQL for the backend. Before proper deployment, for testing purposes, I am accessing my application from another computer that is on the same network. The application, however, is throwing an error when I try to login.
VM12:1 POST http://localhost:3000/auth net::ERR_CONNECTION_REFUSED
Here's my backend code:
server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mysqlConnection = require('./connection');
const routes = require('./routes');
const http = require('http');
const path = require('path');
var app = express();
app.disable('x-powered-by');
app.use(express.static(__dirname + '/dist'));
app.get('/*', (req, res) => res.sendFile(path.join(__dirname)));
app.use(cors());
app.use(bodyParser.json());
app.use(routes);
const port = process.env.PORT || 3000;
const server = http.createServer(app);
server.listen(port, '0.0.0.0', () => console.log(`Running on port ${port}`));
routes.js
router.post("/auth", (req, res) => {
var email = req.body.email;
var password = req.body.password;
var accessBasic = "Basic";
var accessPremium = "Premium";
mysqlConnection.query("SELECT * FROM authorization WHERE email = ? AND password = ?", [email,
password], (err, results) => {
if(!err)
{
var myJSON = JSON.stringify(results);
var check_email = myJSON.search(/email/i);
var check_password = myJSON.search(password);
var check_access = myJSON.search(accessBasic);
var check_access2 = myJSON.search(accessPremium);
if ((check_email != -1) && (check_password != -1) && (check_access != -1))
{
res.send("Successfully Authorized to Basic Access");
}
else if ((check_email != -1) && (check_password != -1) && (check_access2 != -1))
{
res.send("Successfully Authorized to Premium Access");
}
else
{
res.send("Authorization failed");
}
}
else
{
console.log("Connection to authorization failed: " + err.message);
}
})
})
I have allowed incoming connections in my firewall and done everything but, couldn't find the reason why my endpoint is refusing to connect while trying to connect on device other than my system on the same network. I don't know what's wrong. Anybody has any idea what am I doing wrong? I have hosted my application on my system and accessing it from another on the same network.
EDIT: Since, this question has gained quite a lot of views, I would like to mention that I didn't change any of the firewall settings as mentioned above. All the default firewall settings of the Windows OS were used. I just deployed the app and ran it.
ANSWER: I was having an issue on the front-end. I was targeting localhost instead of the IP address of the system that the app was hosted on. See my answer below for the details.
For anyone who is going to see this in future. I was having an error on my front-end. Instead of calling http://localhost:3000/name-of-my-api-endpoint, I changed the localhost to the IP address of my system and then ran ng build --prod again in order to make new static files and serve them from node.js.
I have experienced the same issue with MongoDB
I have found out that the problem was my MongoDB wasn't connected to my localhost and the issue was related to tokens and authentication.
So I went to my terminal on my backend folder and ran the command -
npm install dotenv --save
Then I created my .env file located in my backend folder
and added the following commands
PORT=3000 APP_SECRET="RANDOM_TOKEN_SECRET"
MONGODB="mongodb+srv://youruser:yourpassword#cluster0.k06bdwd.mongodb.net/?retryWrites=true&w=majority"
Then called it in my app.js file
const dotenv = require("dotenv");
dotenv.config();
mongoose.connect(process.env.MONGODB,
{ useNewUrlParser: true,
useUnifiedTopology: true })
.then(() => console.log('Connected to MongoDB!'))
.catch(() => console.log('Failed to connect to MongoDB !'));
module.exports = app;
Finally I have added it in my backend/controllers/user.js
const token = jwt.sign(
{userId: user._id},
process.env.APP_SECRET,
{expiresIn: '24h'});
res.status(200).json({
userId: user._id,
token: token
});
You can access your app in the same network from your #IP not from localhost (127.0.0.1) change it to 192.168.1.X (your local #IP address) and make sure to changed it in your .env file.
I have a personal AWS server running MongoDB 4.0.1 and Docker version 17.03.2-ce, build f5ec1e2
I just got the latest version of node.js (10.9)
I can connect, view and edit documents on MongoDB using Compass.
When I run my node.js on my dev computer, I can use postman to get and post.
When I build a docker container and run it on the AWS docker postman returns ECONNREFUSED.
//index.js
const express = require('express');
const cors = require('cors');
// set up express app
const app = express();
app.use(cors());
app.use(express.json());
//initialize routes - set router to
app.use('/database', require('./routes/recipes'));
// listen for requests
const PORT = 4000;
const HOST = '0.0.0.0';
app.listen(PORT, HOST, function () {
console.log('now listening for requests');
});
//recipes.js
const express = require('express');
const router = express.Router();
const MongoClient = require('mongodb');
const url = 'mongodb://localhost:27017';
//const url = 'mongodb://localhost/local';
// get a list of recipes
router.get('/recipes', function (req, res) {
...
replace localhost with the AWS PRIVATE IP address, not the public one or the public url.
const url = 'mongodb://localhost:27017';
I have a simple app where I'm trying to log to the console (terminal where I started Node, not the the browser console). Express seems to execute the route since I can see the response in my browser.
Also the logging in the app.listen(..) seems to work, but I don't see any logs afterwards.
'use strict';
// 3rd-party dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const dbSetup = require('./db-setup');
// Application config
const LOCAL_APP_PORT = 8080;
const PUBLIC_APP_PORT = process.env.PUBLIC_APP_PORT || LOCAL_APP_PORT;
global.dbType = process.env.DB_TYPE;
// Sanity check for debugging
console.log("local app port:", LOCAL_APP_PORT);
console.log("public app port:", PUBLIC_APP_PORT);
console.log("db type:", global.dbType);
// Database setup for either MongoDB or Postgres
dbSetup(global.dbType);
// Express middleware
app.use(bodyParser.json()); // for parsing application/json
// Import routes
//const index = require('./routes/index');
//const owner = require('./routes/owner');
//const shop = require('./routes/shop');
//const product = require('./routes/product');
// Set up express routes
app.use('/',(req,res,next) => {
console.log("This is not showing on the terminal.");
res.send("This is sent to the browser");
next();
})
//app.use('/owner', owner);
//app.use('/shop', shop);
//app.use('/product', product);
app.listen(LOCAL_APP_PORT, () => {
console.log('App started ...');
});
EDIT: Solved. Problem was my app was basically available on two ports at the same time. One the the public port however it was not showing any logs...
Terminal screenshot