Cannot connect to MongoDB via env variable - node.js

I am trying to conceal my connection string, so I installed env2 in my project. Then I made a config.env file that keeps my connection string like this:
export DB_URL='mongodb://user:userPassword#ds241968.mlab.com:41968/heroku_hc9xjmcl'
However when I use that variable as a connection string I cannot connect to Mlab I get the following error:
UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [ds241968.mlab.com:41968] on first connect [MongoError: Authentication failed.]
But when I try to connect only with the string without using env2 I connect perfectly, so why does the ahuthentication fail when I use a env variable and how can I connect with one properly? Here is my server.js:
// Requiring the dependencies
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const PORT = process.env.PORT || 3009;
const itemRoutes = express.Router();
let Comment = require('./comment.model');
const env = require('env2')('../config.env');
console.log(process.env.DB_URL)
app.use(cors());
app.use(bodyParser.json());
const { DB_URL } = process.env;
mongoose.connect( DB_URL , { useNewUrlParser: true } )
const connection = mongoose.connection;
connection.once('open', function() {
console.log('Connection to MongoDB established succesfully!');
});
// Serve static assets
if(process.env.NODE_ENV === 'production') {
app.use(express.static('build'));
}
itemRoutes.route('/').get( async (req, res) => {
let collection = connection.collection("posts");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/comments').get( async (req, res) => {
let collection = connection.collection("comments");
let response = await collection.find({})
.toArray();
res.send(response);
});
itemRoutes.route('/userComments')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
let comment = new Comment(req.body);
comment.save()
.then(comment => {
res.status(200).json({comment})
})
.catch(err => {
res.status(400).send('failed')
})
});
app.use('/', itemRoutes);
app.use('/userComments', itemRoutes);
app.listen(PORT, function() {
console.log('Server is running on' + ' ' + PORT);
})

Looks like you are using Node and Heroku. In that case,
You should set Heroku Config Vars (you can do this either via CLI or your Heroku Dashboard)
Refer to the config var in your node application the same way you are referring to now.
Remove 'env2' related code as you won't need it for this purpose
For example, if you create Heroku config var called "MONGO_URI", refer to it as process.env.MONGO_URI in your node application.
Details can be found here: https://devcenter.heroku.com/articles/config-vars#managing-config-vars

Related

Node Express Mongo app goes sleep mode in shared cPanel

I deployed a Node js server with Express Js and MongoDB on NameCheap cPanel. The problem is I have to refresh 2 or 3 times to get the data from the server.Otherwise its gives 404. Then it works fine but after some minutes it acts the same. I have to refresh 2 or 3 times.
`
const express = require("express");
const { MongoClient } = require("mongodb");
const cors = require("cors");
require("dotenv").config();
const app = express();
const port = process.env.PORT || 5000;
//Middleware
app.use(cors());
app.use(express.json());
//MongoDB linking
const uri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASS}#xyz`;
const client = new MongoClient(uri);
async function run() {
try {
await client.connect();
//DB Folder and Subfolder
const database = client.db("XYZ");
const allUsers = database.collection("All-Users");
app.get("/allusers", async (req, res) => {
const get = allUsers.find({});
const allData = await get.toArray();
res.send(allData);
});
} finally {
//await client.close();
}
}
run().catch(console.dir);
app.get("/", (req, res) => {
res.send(" Server is running just fine");
});
app.listen(port, () => {
console.log(" server running on port :", port);
});
`
I dont have idea what the problem is. Did anyone faced the same issue, and solved the issue?
Thank you.

Postman: Connect ECONNREFUSED 127.0.0.1:5005

I have developed an API endpoint. It was working fine before. Unfortunately the project folder got corrupted (I recreated the files db.js and server.js). But now when I try to fetch data from API, I'm getting:
"connect ECONNREFUSED 127.0.0.1:5005"
The URL I'm using is localhost:
And my server is running on the same port i.e. 5005:
Can someone please elaborate what can be the problem? My hunch is that when I recreated the files I may have missed something:
db.js:
const mongoose = require('mongoose');
const userName = "myUsername"
const password = "myPassword"
const dbName = "comfyRooms"
const dbURL = `mongodb+srv://${userName}:${password}#mongo-cluster.damzf.mongodb.net/${dbName}?authSource=admin&replicaSet=atlas-s7z01e-shard-0&readPreference=primary&appname=MongoDB%20Compass&ssl=true`
mongoose.connect(dbURL, {useUnifiedTopology: true, useNewUrlParser: true})
let connection = mongoose.connection
connection.on('error', () => {
console.log('Unable to connect to MongoDB')
})
connection.on('connected', () => {
console.log("MongoDB connection established :)")
})
module.exports = mongoose
server.js
const express = require('express')
const app = express()
const dbConfig = require('./db')
const roomsRoute = require('./routes/roomsRoute')
app.use('/api/rooms', roomsRoute)
const port = process.env.PORT || 5005
app.listen(() => {
console.log("Node JS server listening on port " + port)
})
roomsRoute.js:
const express = require('express');
const router = express.Router();
const Room = require('../models/rooms');
router.get('/getallrooms', async (req, res) => {
try {
const rooms = await Room.find({});
return res.send(rooms);
} catch (error) {
return res.status(400).json({message: error});
}
});
module.exports = router;
I have attached the important files. Please let me know if any other information is missing. Thanks!
You are not passing the port variable to the listen function, you are just logging it
app.listen(() => {
console.log("Node JS server listening on port " + port)
})
This should work
app.listen(port, () => {
console.log("Node JS server listening on port " + port)
})

Express API | Heroku - JWT (error - secret or private key must have a value)

I deployed my API to Heroku and when I try to use it (login). I get some errors.
my code -
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const cors = require("cors");
// IMPORT FILES
const user = require("./routes/user");
// MONGOOSE CONNECTION
mongoose.connect(
"CONNECTION URL HERE",
{ useNewUrlParser: true },
() => {
console.log("Connected to DB");
}
);
// MIDDLEWARE CONFIGS
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
mongoose.Promise = global.Promise;
// ROUTES REDIRECTION
app.use("/", user);
// SERVER
const server = app.listen(process.env.PORT || 8080, () => {
const port = server.address().port;
console.log(`Server is running on port ${port}`);
});
JWT FILE
const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {
const token = req.header("token");
if (!token) return res.status(401).send("please login again");
try {
const verify = jwt.verify(token, "JWT SECRET HERE");
req.user = verify;
next();
} catch (err) {
res.status(400).send("invalid token");
}
};
Some pictures of errors-
Error in Heroku logs --tails
error is browser
PS: i had .env for the variables but took 'em out for delpoyment's sake as I was getting Application error.
thank you! help is appreciated.
Have you added your environment variables to heroku config vars?
If not then follow the heroku documentation to do so.
https://devcenter.heroku.com/articles/config-vars
You can use the heroku cli or use the heroku dashboard to add the variables. Refer the docs for a detailed explanation.

Can't retrieve information from mongodb when deploying on heroku

The problem is as the title suggests. When I run my app locally, I'm able to retrieve information from MongoDB but on Heroku, undefined is returned. Should I connect to MongoDB in another way because if I hardcode some text everything works just fine. Here are my scripts:
function to get data
const MongoClient = require("mongodb").MongoClient;
const dbConnectionUrl = "mongodb+srv://xxxxxxx#cluster0.ro4dz.mongodb.net/data?retryWrites=true&w=majority";
const saySomething = (req, res, next) => {
// res.status(200).json({
// body: 'Hello from the server!'
// });
login()
.then(val=>res.send(val))
};
async function login(){
const client = new MongoClient(dbConnectionUrl)
try{
await client.connect();
const database = client.db("data");
const movies = database.collection("movies");
const query = { name: "toke" };
const movie = await movies.findOne(query);
return movie
}catch(err){
console.log(err)
}
}
module.exports.saySomething = saySomething;
router
const express = require('express');
const router = express.Router();
const controllers = require('./../controllers/controllers');
router.get('/say-something', controllers.saySomething);
module.exports = router;
server
// Import dependencies
const express = require('express');
const cors = require('cors');
const path = require('path');
// Create a new express application named 'app'
const app = express();
// Set our backend port to be either an environment variable or port 5000
const port = process.env.PORT || 5000;
// This application level middleware prints incoming requests to the servers console, useful to see incoming requests
app.use((req, res, next) => {
console.log(`Request_Endpoint: ${req.method} ${req.url}`);
next();
});
// Configure the CORs middleware
// Require Route
app.use(cors());
const api = require('./routes/routes');
// Configure app to use route
app.use('/api', api);
// This middleware informs the express application to serve our compiled React files
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'staging') {
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
});
};
// Catch any bad requests
app.get('*', (req, res) => {
res.status(200).json({
msg: 'Catch All'
});
});
// Configure our server to listen on the port defiend by our port variable
app.listen(port, () => console.log(`BACK_END_SERVICE_PORT: ${port}`));
front
import { useEffect, useState } from 'react';
import './App.css';
import axios from 'axios'
function App(){
useEffect(()=>{
get()
})
const[text, settext] = useState('')
async function get(){
let request = await axios.get('/api/say-something')
console.log(request.data.name)
settext(request.data.name)
}
return(
<div>{text}</div>
)
}
export default App;
I solved the issue! The first thing I did was that I added MongoDB connection URI as an environmental variable in my app via Heroku. Secondly, I added an option in MongoDB so that the cluster can be accessed from any computer. By default, the access is set to the local computer so I added another IP, namely 0.0.0.0/0 to my cluster, and now everything works just fine.

Node js & mongoDB - TypeError: db.collection is not a function

I am trying to post data from POSTMAN to an external database that I created on mLab but I am getting the error db.collection is not a function.
There is a similar question thread but the answer is incomplete and doesn't save any keys/values I put into postman to mLab. The code that I am trying to make work is from this tutorial: https://medium.freecodecamp.com/building-a-simple-node-js-api-in-under-30-minutes-a07ea9e390d2
My Code:
Server.js
const express = require('express'); // Load routes application
const MongoClient = require('mongodb').MongoClient; //Load database connection application
const db = require('./config/db');
const app = express(); // Assign express app a variable
const port = 8000; //Set local port value for server
const bodyParser = require('body-parser'); // **This has to come BEFORE routes
var assert = require('assert'); // ?
var databaseURL ='mongodb://external:api#ds123312.mlab.com:23312/soundfactory';
app.listen(port, () => {
console.log('')
console.log('We are live on ' + port);
console.log('')
});
MongoClient.connect(databaseURL, function(err, db) {
assert.equal(null, err);
console.log("API has succesfully connected to Sound Facotry mlab external database.");
console.log('')
db.close();
});
app.use(bodyParser.urlencoded({ extended: true }))
require('./app/routes')(app, {}); //Must come AFTER express w/ body parser
db.js
module.exports = {
url : 'mongodb://external:api#ds123312.mlab.com:23312/soundfactory'
};
index.js
const noteroutes = require('./note_routes');
module.exports = function(app,db)
{
noteroutes(app,db);
};
note_routes.js
module.exports = function(app, db) {
app.post('/notes', (req, res) => {
const note = { text: req.body.body, title: req.body.title };
db.collection('notes').insert(note, (err, result) => {
if (err) {
res.send({ 'error': 'An error has occurred' });
} else {
res.send(result.ops[0]);
}
});
});
};
partially correct code
server.js (code that partially works & doesn't throw the db.collections error like my original server.js file )
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const bodyParser = require('body-parser');
const db = require('./config/db');
const app = express();
const port = 8000;
app.use(bodyParser.urlencoded({extened:true}));
MongoClient.connect(db.url,(err,database) =>{
if (err) return console.log(err)
//require('./app/routes')(app,{});
//check below line changed
require('./app/routes')(app, database);
app.listen(port,() => {
console.log("We are live on"+port);
});
})
Remove the node_modules folder and change mongodb version of your package.json
"mongodb": "^2.2.33"
and run below code :
npm install
change to this require('mongodb').MongoClient;

Resources