Connected to MLab, but won't connect to localhost - mongodb

I had this working fine on both localhost and MLab, but then had to switch databases. After much trying I got the database up on MLab, but now it's not connecting to my localhost. Here is my server.js file:
const path = require("path");
const PORT = process.env.PORT || 3001;
const app = express();
const mongoose = require("mongoose");
const routes = require("./routes");
// Connect to the Mongo DB
mongoose.connect(process.env.MONGODB_URI || 'mongodb://XXUSERXX:XXPASSWORDXX#ds217388-a0.mlab.com:17388,ds217388-a1.mlab.com:17388/<dbname>?replicaSet=rs-ds217388', { useNewUrlParser: true });
mongoose.connection.on("open", function (ref) {
console.log("Connected to mongo server.");
});
mongoose.connection.on('error', function (err) { console.log(err) });
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
// Add routes, both API and view
app.use(routes);
// Define API routes here
// Send every other request to the React app
// Define any API routes before this runs
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});
app.listen(PORT, () => {
console.log(`🌎 ==> API server now on port ${PORT}!`);
});
The only line of code I changed was this one below, this is what it was previously:
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/wineDB', { useNewUrlParser: true });
I have this app connected in Heroku and had MONGODB_URI defined in the Config Vars, but it wasn't working with the second database until I manually put the connection string in my server.js file. It worked fine with the first one, I don't understand why!
How do I get it to connect to find localhost when it's not running off of MLAB so I can test? Thanks for the help.

It looks like the confusion is from a few different combinations of whether the environment variable being defined or not, as well as whether or not your app is using the variable, instead of falling back to what is defined.
The MONGODB_URI environment variable should contain the connection string for your mLab database and be defined in your Heroku environment both locally and when deployed. I'm assuming that the variable process.env.LOCAL will only be present on your local environment, in situations where your app should be connecting to the local database.
In these cases, something like the following should work:
if(process.env.LOCAL || process.env.MONGODB_URI) {
mongoose.connect(process.env.LOCAL || process.env.MONGODB_URI, { useNewUrlParser: true });
...
} else {
console.log("MongoDB connection string not defined!");
}
We place process.env.LOCAL first, followed the by ||, to say that it gets preference when connecting. Mongoose should then connect to whatever is defined in process.env.LOCAL if present (i.e. your local MongoDB database), falling back to process.env.MONGODB_URI (i.e. mLab) otherwise.
Lastly, it's wrapped in a simple if-else to print out an error message if both values are not defined.

Related

Connecting to Heroku Postgres from Auth0 results in: err no pg_hba.conf entry for host, no encryption

I'm trying to connect to my PostgreSQL database hosted on Heroku through Auth0's Database Connections.
I am getting an error when I try to invoke the Get User script within Auth0's database actions:
no pg_hba.conf entry for host "xx.xxx.xx.x", user "xxx", database "xxx", no encryption
The script looks like this:
function loginByEmail(email, callback) {
const postgres = require('pg');
const conString = configuration.DATABASE_URL;
postgres.connect(conString, function (err, client, done) {
if (err) return callback(err);
const query = 'SELECT id, nickname, email FROM organizations WHERE email = $1';
client.query(query, [email], function (err, result) {
done(); // Close the connection to the database
if (err || result.rows.length === 0) return callback(err);
const user = result.rows[0];
return callback(null, {
user_id: user.id,
nickname: user.nickname,
email: user.email
});
});
});
}
Connection String:
configuration.DATABASE_URL: 'postgres://xxx:xxx#xxx?sslmode=require'
I appended sslmode=require to the end of my connection string to ensure I have a SSL connection to my database.
I have also tried changing sslmode=require to ssl=true, which results in a different error:
self signed certificate
I am unsure where to go from here, so any help would be appreciated.
You should first establish the client and specify the rejectUnauthorized flag, like so:
const client = new postgres.Client({
connectionString: conString,
ssl: { sslmode: 'require', rejectUnauthorized: false }
});
Then, instead of using your postgres to connect, use the client:
client.connect();
client.query(...);
This should solve your problem, and the connection will be encrypted. You won't, however, be protected against Man-In-The-Middle (MITM) attacks, as specified in documentation.
#Pexers solution worked for me, however, somehow it shows TypeScript error. The way I did it is just ssl: true:
const client = new postgres.Client({
connectionString: conString,
ssl: true
});

Next.js middleware to connect mongoose

I am working on a Next.js project and I want to connect it with MongoDB using mongoose. I want to make a middleware to run the connect function inside so I don't have to call connect function in each file I am using a mongoose model in.
this is my connect file:
// src/utils/connect.js
import mongoose from 'mongoose'
// getting the connection uri
const MONGO_URI = process.env.MONGO_URI
// checking if MONGO_URI is defined
if (!MONGO_URI) {
throw new Error(
'Please define the MONGO_URI environment variable inside .env.local'
)
}
// maintaining a cached connection to prevent reconnection (connections growing exponentially during API Route usage)
let cached = global.mongoose
// restiing the connection if there was no cached connection
if (!cached) {
cached = global.mongoose = null
}
/**
* mongodb connection
*/
export default async function connect() {
// returning the cached connection if it exists
if (cached) {
return cached
}
cached = await mongoose.connect(MONGO_URI, {
bufferCommands: false,
useNewUrlParser: true,
useUnifiedTopology: true
})
return cached
}
it will connect mongoose with my MongoDB database and caches the connection for future use.
this is one of my example API routes:
// src/pages/api/test.js
import connect from '../../utils/connect'
import Test from '../../models/Test';
export default async function handler(req, res) {
// connect
await connect()
const data = await Test.find({});
res.status(200).json({ name: 'John Doe', data })
}
now what I want to do is to get rid of that await connect() function in all routes and instead make a middleware to run the connect. and also is it better do so or not?

MongooseServerSelectionError: In Cpanel , Simple Routes are working But whenever try to Hit route of (MongoDb get/set) its Not Working. Mongodb error

Hy I have React NodeJs App, Trying to Deploy it On Cpanel Namecheap...
The site is Deploy Correctly. And Simple Routes are also Working but Routes that use to get/set data from DB is Note Working and stay in a loading state for long time...
I Also See my stderr.log file it says "MongooseServerSelectionError"...
But my MongoDB NetworkAccess is a enter image description herepublic already!!!!
Please Help..
here is my connection Code start.....
const mongoose = require("mongoose");
const connectDb = async () => {
mongoose.connect(
"mongodb://serverBoiler:myPassword#cluster0-shard-00-00.t30x6.mongodb.net:27017,cluster0-shard-00-01.t30x6.mongodb.net:27017,cluster0-shard-00-02.t30x6.mongodb.net:27017/RagdollCatServer?ssl=true&replicaSet=atlas-1r1rhb-shard-0&authSource=admin&retryWrites=true&w=majority",
{
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
}
)
.then((res) => console.log(`Db connected on ${res.connection.user}`));
};
module.exports = connectDb;
////////////////////////////////////////////////////////////////////////
You better try with localhost like this
it may help full I think.
var db="mongodb://localhost/loginapp"
mongoose.connect(db,{useNewUrlParser: true})
.then(()=>console.log('MongoDB successfully connected'))
.catch(err=>console.log(err));

MongoDB connection error in Digital Ocean droplet

I am in the process of deploying my MERN app to a Digital Ocean droplet (Ubuntu 20.04 server).
I have cloned my GitHub repo to the droplet, installed the dependencies using npm install. Next, when I am starting the server using npm start, I get the following error:
The error essentially says that the first parameter to mongoose.connect() is undefined and must be a string. However, everything works fine in my local machine and when I console.log process.env.MONGO_URI, I get the connection string.
server/config/db.js
const mongoose = require("mongoose");
const colors = require("colors");
const dotenv = require("dotenv");
dotenv.config();
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
console.log(`MongoDB connected: ${conn.connection.host}`.cyan.bold);
} catch (error) {
console.error(`Error: ${error.message}`.red.bold.underline);
process.exit(1);
}
};
2;
module.exports = connectDB;
Why am I getting this error while starting the server in my Digital Ocean droplet?
dotenv doesn't load system variables.
Create .env file with
MONGO_URI=XXXXXXX
https://github.com/motdotla/dotenv#usage
Create a .env file in the root directory of your project. Add
environment-specific variables on new lines in the form of NAME=VALUE.
For example:
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3

Parse Server - Image files' path returns localhost

I have deployed 2 Ubuntu servers on Azure. First, I have installed the Parse Server and the second, I installed MongoDB. (I have also put a ready db there from my previous server via mongorestore)
Everything works fine! Both Parse Server and MongoDB server. They also communicate well. The thing is, when I run my iOS app, it brings all data correctly, except images. I print the URL of an image and here's what it returned: http://localhost:1337/parse/files/filename.jpeg
If I replace localhost with my server's ip, the image is being fetched nicely!
Here's what I have on my index.js:
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var ParseDashboard = require('parse-dashboard');
var allowInsecureHTTP = true;
var path = require('path');
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 || 'mongodb://IP:27017/db',
cloud: './cloud/main.js',
appId: process.env.APP_ID || 'xxx',
masterKey: process.env.MASTER_KEY || 'xxx', //Add your master key here. Keep it secret!
fileKey: 'xxx',
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't forget to change to https if needed
// Enable email verification
verifyUserEmails: false,
// The public URL of your app.
// This will appear in the link that is used to verify email addresses and reset passwords.
// Set the mount path as it is in serverURL
publicServerURL: 'http://localhost:1337/parse',
});
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
// If you wish you require them, you can set them as options in the initialization above:
// javascriptKey, restAPIKey, dotNetKey, clientKey
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// 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('Make sure to 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 + '.');
});
// Set up parse dashboard
var config = {
"allowInsecureHTTP": true,
"apps": [
{
"serverURL": "http://localhost:1337/parse",
"appId": "xxx",
"masterKey": "xxx",
"appName": "name",
"production": true
}
],
"users": [
{
"user":"username",
"pass":"pass"
}
]
};
var dashboard = new ParseDashboard(config, config.allowInsecureHTTP);
var dashApp = express();
// make the Parse Dashboard available at /dashboard
dashApp.use('/dashboard', dashboard);
// Parse Server plays nicely with the rest of your web routes
dashApp.get('/', function(req, res) {
res.status(200).send('Parse Dashboard App');
});
var httpServerDash = require('http').createServer(dashApp);
httpServerDash.listen(4040, function() {
console.log('dashboard-server running on port 4040.');
});
One thing I noticed at Parse's documentation, is this: When using files on Parse, you will need to use the publicServerURL option in your Parse Server config. This is the URL that files will be accessed from, so it should be a URL that resolves to your Parse Server. Make sure to include your mount point in this URL.
The thing is that this documentation was written having in mind MongoDB, is on the same server with Parse, which in my case isn't.
Any ideas on what to do?
I had to replace the publicServerURL of parse server's config, from http://localhost:1337/parse to http://publicIP:1337/parse and everything worked out great!
If you want to work with files(images) download them, just use publicServerURL as mentioned #Sotiris Kaniras
I would add that the config.json is in ~/stack/parse/config.json. Also here is the difference between serverURL and publicServerURL
Difference between serverURL and publicServerURL on ParseServer
In my case, I needed to add publicServerURL parameter alongside with serverURL because it hasn't existed yet.
So both parameters(publicServerURL & serverURL) are complement, not mutually exclusive, use them both.