I'm working on creating an anonymous discussion forum where I've deployed my MongoDB on MongoDB Atlas (cloud platform) using Heroku. The whole app is developed using React. Here is my code for server.js:
var express = require('express');
const path = require('path');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var models = require('./api/models/message');
var routes = require('./api/routes/routes');
var port = process.env.PORT || 3001;
var app = express();
var Message = mongoose.model('Message')
// Uncomment this line to run it on development mode (localhost) -- discussion is our db name //
// mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/discussion');
// This line is working on production mode //
mongoose.connect(process.env.MONGODB_URI || 'mongodb+srv://xxx:xxx#cluster0-xucmg.mongodb.net/test?retryWrites=true&w=majority');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
routes(app);
if (process.env.NODE_ENV === "production") {
app.use(express.static("frontend/build"));
console.log("production");
}
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, 'frontend/build', 'index.html'))
});
app.listen(port);
console.log('Server running on port ' + port);
My database name is discussion. When this line is uncommented:
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/discussion');
The database loads fine and frontend code also works fine on localhost.
But I'm trying to host my database on the cloud (to resolve issues with Heroku build) with this line:
mongoose.connect(process.env.MONGODB_URI || 'mongodb+srv://xxx:xxx#cluster0-xucmg.mongodb.net/test?retryWrites=true&w=majority');
I'm not sure why because of this line the frontend part is not being loaded (on Heroku deployment link). I assume maybe this is because of database not being loaded. But, it'll be a great help if anyone can help me figure out this issue. I tried to follow this solution: Connecting Heroku App to Atlas MongoDB Cloud service by providing whitelist access but the issue still persist.
I fixed this issue by updating the mongoose dependency version >= 5.0.0
Even after adding CIDR as 0.0.0.0/0 in IP whitelist in MongoDB Atlas, updating mongoose version will help to overcome this type of issue.
Related
So i recently created an Account at heroku.com and created a PostgreSQL database. First of all i wanted to test if i could store something into the database (One table was already created without node.js) but for some odd reason the callback function of my dbClient.query never executed. I then realized that the Database does not connect to my code. My password, host, etc. should all be right and i can connect from extern sites but not from my node.js code.
Here´s my code:
var express = require("express");
var pg = require("pg");
var bodyParser = require("body-parser");
var CON_STRING = process.env.DB_CON_STRING;
if (CON_STRING == undefined) {
console.log("Error: Environment variable DB_CON_STRING not set!");
process.exit(1);
}
pg.defaults.ssl = true;
var dbClient = new pg.Client(CON_STRING);
dbClient.connect();
var urlencodedParser = bodyParser.urlencoded({
extended: false
});
var PORT = 3000;
var app = express();
app.set("views", "views");
app.set("view engine", "pug");
app.get("/shoppingitems", function (req, res) {
res.render("shoppingitems")
});
app.post("/shoppingitems", urlencodedParser, function(req, res){
var shoppingItem = req.body.shoppingItem;
dbClient.query("INSERT INTO shoppinglist (title) VALUES ($1)", [shoppingItem], function(dbError, dbResponse){
console.log("function called!");
res.redirect("/shoppingitems");
})
console.log("test");
})
app.listen(PORT, function () {
console.log(`Shopping App listening on Port ${PORT}`);
});
It does not work with other configs of dbClient.query.
You need to set the environment variable on your localhost, depending on your OS.
For Mac & Linux use 'export' keyword in Terminal for YOUR_ENV_VAR, example:
export DB_CON_STRING=postgres://ufohlgoihdgfalr:2fb913jhazsxd541469b972fcac862ddf664620998e87c96787569poiude4ab0b#ec2-34-238-26-109.compute-1.amazonaws.com:5432/d587yhytte32gj
You can check your variable using 'echo' and $ sign in Mac and Linux, for example
echo $DB_CON_STRING
It should give you the string if the variable is set or not.
Note that will be only work for the current session in the Terminal, if you want to keep it and use it for a long time or after closing/opening the terminal then it is better to add it to your .bash_profile. Same way, just make it saved in the /uerMacUser/.bash_profile
For windows you can do it using GUI, for quick access use in 'Run' rundll32.exe sysdm.cpl,EditEnvironmentVariables
Heroku Postgres uses different environment variable named 'DATABASE_URL' so you might want to consider this if you want to deploy on heroku later, otherwise your application will not start on heroku.
I am a beginner to MERN stack development.I have deployed my nodejs app without any error on heroku.But the app does not load the data from mongodb atlas database.The app connects to database and displays the data without any problem when run locally.Any ideas on how to fix this?
I have already added environment variable on heroku and whitelisted all ip addressed on atlas.But still the app does not load data from the database
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;
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}`);
});
http://justworkout.herokuapp.com/
This is the app url
The list of exercises should load from the database but nothing is loaded as you can see
I had the same problem. The solution for me it was to go to my client folder and change all my fetch methods. For fetching data I'm using axios. I was sending request to localhost:5000 and then /api/etc. The request was something like this:
axios.get("http://localhost:5000/apps/blog").then()
To make it work on heroku I needed to remove the prefix of localhost and leave just the api path.
axios.get("/apps/blog").then()
Changing this sort my problem.
I am trying to make calls to my database from my react/node app hosted on a server. When run locally (using nodemon) the application is running at localhost:3000 and the server is hosted on port 4000, so I make api calls to localhost:4000. For example, localhost:4000/students displays the list of students stored in the MongoDB.
My server.js is as follows:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const mongoose = require('mongoose');
const studentRoute = require('./student.route');
const config = require('./secrets');
mongoose.Promise = global.Promise;
mongoose.connect(config.dbUri, { useNewUrlParser: true }).then(
() => {console.log('Database is connected') },
err => { console.log('Can not connect to the database'+ err)}
);
I am deploying my application to my site by uploading the build folder that results from npm run build to a folder called 'the-wall' (the name of the project). So to access the application I go to example.com/the-wall.
My mongoDB is hosted using MongoDB atlas, and have whitelisted my IP address and what I believe to be the IP address of the server. I am making calls using axios, with the following config:
const env = process.env.NODE_ENV;
export const app = axios.create({
baseURL:
env === 'production'
? 'https://example.com:4000/'
: 'http://localhost:4000/',
});
However, when I try to access example.com:4000/student I receive a net::ERR_CONNECTION_REFUSED error. As far as I can tell, mongoDB is not installed on the server. Is the URL I am using incorrect, or is there additional set up I need to do?
Note: I have also tried example.com/the-wall:4000/student, but I get a 404 error with this one.
Does the way I am trying to make a call to the database look correct? (i.e. is the URL correct with the port, etc)
Try to make it works locally with the production database.
If it works, it's an IP configuration problem on your server.
If it fails, it's a code configuration problem.
I have been stuck longer than I would like, with a problem related to email verification when creating an account on Parse-Server (/Heroku). Though I made a few post on the issue, I was not lucky enough (or maybe did not formulate things clearly enough) to get significant help. So I decided to do it all over again, this time giving a precise step by step way to reproduce the bug, for anyone interested in taking a close look. If what I do is right from start to end, then there must be a bug. If on the other hand I do something wrong (this is most probably the case), I hope somebody can point out the mistake.
Here is the process, start by creating an app on heroku, using the following commands at the terminal:
git clone https://github.com/parse-community/parse-server-example.git
mv parse-server-example linkbugapp808
cd linkbugapp808/
npm install #parse/simple-mailgun-adapter --save
heroku create linkbugapp808
heroku addons:create mongolab:sandbox
heroku config:set APP_ID=ABCDEF-12345678:xytzt_SSTTJJZ
heroku config:set MASTER_KEY=MMMMM-87878787:wwyyssaa_PPGHYU
heroku config:set SERVER_URL=https://linkbugapp808.herokuapp.com/
heroku config:set PARSE_PUBLIC_SERVER_URL=https://linkbugapp808.herokuapp.com
Of course if the name I use "linkbugapp808" is taken or you don't like it you may choose another one.
Set the index.js file as this (fixing the mailgun parameters that need to be fixed, to fit you environment):
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var mongo = require('mongodb');
var MongoClient = mongo.MongoClient;
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri,
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID,
masterKey: process.env.MASTER_KEY,
serverURL: process.env.SERVER_URL,
publicServerURL: process.env.PARSE_PUBLIC_SERVER_URL,
appName: 'LinkBugApp',
verifyUserEmails: true,
emailAdapter: {
module: '#parse/simple-mailgun-adapter',
options: {
fromAddress: 'from#somemail.com',
domain: 'some.domain',
apiKey: 'key-apiKey-mailgun-apiKey'
}
}
});
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('I dream of being a website. Please star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);
Next run the following command in the terminal (inside the linkbugapp808 root folder):
git add . && git commit -m "update linkbugapp808" && git push heroku master
At this point the app is created on Heroku and ready to go.
Then from an iOS app create an account on the Parse-Server we just set above.
All seems to go fine.
The user for whom the account was created will receive a mail similar to this one:
Hi,
You are being asked to confirm the e-mail address usermail#xmail.com with LinkBugApp
Click here to confirm it:
https://linkbugapp808.herokuapp.com/apps/ABCDEF-12345678:xytzt_SSTTJJZ/verify_email?token=SiYyk9NgVkcwhXXWlEdEUTjyz&username=ausrnamex
When clicking the confirmation link inside the mail this is what one can see (not exactly what is expected from a sign up confirmation link):
Cannot GET /apps/ABCDEF-12345678:xytzt_SSTTJJZ/verify_email?token=SiYyk9NgVkcwhXXWlEdEUTjyz&username=ausrnamex
I have tried with several browsers, but the result is identical.
Why do we get into this situation?
I have been following the Heroku Stormpath docs to setup a simple Express app. The code from my server.js file is shown below:
'use strict';
var express = require('express');
var pg = require('pg');
var stormpath = require('express-stormpath');
var app = express();
app.use(express.static('public'));
app.use(stormpath.init(app, {
apiKeyFile: '/.stormpath/apiKey.properties',
apiKeyId: process.env.STORMPATH_API_KEY_ID,
apiKeySecret: process.env.STORMPATH_API_KEY_SECRET,
secretKey: process.env.STORMPATH_SECRET_KEY,
application: process.env.STORMPATH_URL,
}));
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function(){
console.log('Node app is running on port', app.get('port'));
});
Forgive me for being a newbie to Stormpath. I've looked through the Express-Stormpath docs as well, but I continue to receive the following error when running the app locally:
Node app is running on port 5000
events.js:141
throw er; // Unhandled 'error' event
^
Error: API key ID and secret is required.
I have provisioned the Stormpath addon via Heroku, and when running heroku config in the terminal I see that all of the variables passed into stormpath.init are available. Can someone enlighten me as to what I am doing wrong?
if you are running your server app locally, I can guess that you didn't create the environment variables so try this:
$ STORMPATH_API_KEY_ID=123 STORMPATH_API_KEY_SECRET=secret STORMPATH_SECRET_KEY=secret STORMPATH_URL=url node app.js
or you can set the storm values whenever they are empty as in your case:
app.use(stormpath.init(app, {
apiKeyFile: '/.stormpath/apiKey.properties',
apiKeyId: process.env.STORMPATH_API_KEY_ID || 'key',
apiKeySecret: process.env.STORMPATH_API_KEY_SECRET || 'secret',
secretKey: process.env.STORMPATH_SECRET_KEY || 'key',
application: process.env.STORMPATH_URL || 'url'
}));
in either case provide your real stormpath values from your addon at heroku.
This is for anyone coming for a solution to this problem.. You should refer the Getting started steps provided by Stormpath!
For express.js refer this.
This might be what you were missing..
Set the environment variables: UNIX
export STORMPATH_CLIENT_APIKEY_ID=5EFMBEN6N34AU36ENEEGJ9YLY
export STORMPATH_CLIENT_APIKEY_SECRET=iII3MZPC2hJC/yuOXMjaa0/0GcgyeApfPVvWyNmMR1c
export STORMPATH_APPLICATION_HREF=https://api.stormpath.com/v1/applications/7F0kZw0wqcFBNh1dDbWMiU
Set the environment variables: WINDOWS
set STORMPATH_CLIENT_APIKEY_ID=5EFMBEN6N34AU36ENEEGJ9YLY
set STORMPATH_CLIENT_APIKEY_SECRET=iII3MZPC2hJC/yuOXMjaa0/0GcgyeApfPVvWyNmMR1c
set STORMPATH_APPLICATION_HREF=https://api.stormpath.com/v1/applications/7F0kZw0wqcFBNh1dDbWMiU