How to connect to a local database from server - javascript

trying to access to an external database in local via my server, I executed this code server side:
console.log('MONGODB_URI_LOCAL::', config.MONGODB_URI_LOCAL)
const mongooseLocal = require('mongoose');
const connectionOptions = { useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false };
const conn = mongooseLocal.createConnection(config.MONGODB_URI_LOCAL, connectionOptions);
conn.on("error", console.error.bind(console, "connection error: "));
conn.once("open", async () => {
console.log("Connected successfully");
});
And I get this error:
MongoError: Authentication failed
here is the format of the URI:
config.MONGODB_URI_LOCAL = mongodb://user_name:my_password#localhost:27017/my_db_name
This is the first time I try to connect to a local database so:
Is this possible to connect to a local database from server and read or write data ?
If yes How can I fix this issue ?

Here's an approach that you can use.
This approach enables you to export your connection logic to other parts of your code.
const mongoose = require('mongoose')
const connect = async (callback) => {
try{
const connectionOptions = {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
};
await mongoose.connect(config.MONGODB_URI_LOCAL, connectionOptions)
// On successful connection you can call your callback function
callback()
}catch(err){
console.log(err)
process.exit(1)
}
}
connect()

Related

How to switch between Mongo databases using Mongoose?

What I want to do is to use different databases for different users, for example I have 3 users that would connect to:
www.user1.myfrontend.com
www.user2.myfrontend.com
www.user3.myfrontend.com
Let's suppose that each user want to display the list of products he has, a GET request would be sent to the backend and from there I will connect to the database of the user:
mongodb://mongodatabse:secret#server/databaseOfUser1
mongodb://mongodatabse:secret#server/databaseOfUser2
mongodb://mongodatabse:secret#server/databaseOfUser3
What I did so far:
I connect to the database called config at the start of the app:
db.js
const connect = (uri, app, database="config") => {
const db= mongoose
.createConnection(uri,{ useNewUrlParser: true, useUnifiedTopology: true })
db.on('open', () => {
mongoose.connection.useDb("config")
app.emit('dbReady');
return true;
});
db.on('error', (err) => {
console.log(`Couldn't connect to database': ${err.message}`);
return false;
});
};
server.js
db.connect(process.env.MONGODB_URL, app);
app.on('dbReady', function () {
server.listen(PORT, () => {
console.info(`> Frontend is hosted #: ${process.env.BASE_URL}`);
console.info(`> Database is hosted #: ${process.env.mongodb_url}`);
console.info(`> Listening on port ${PORT}`);
});
});
Then whenever I receive a request I check in the config database for the database to use:
app.js:
const AccessConfig = require('./models/schemas/AccessConfigSchema');
const db = require('./models/db');
app.use(async (req, res, next) => {
const subdomain = req.subdomains[req.subdomains.length - 1];
try {
let database = await AccessConfig.findOne({ subdomain: subdomain});
if (!database)
database= await AccessConfig.findOne({ subdomain: "demo"});
console.log(database);
db.useDb(database);
next();
} catch (e) {
console.log(e.message)
return res.status(500).send('Error: ' + e.message);
}
});
So far It seems like the database isn't changing and I'm not even sure that this is the correct implementation or too many connections are open, etc.
I figured out, you can create connections using
//DB_URI_USER1=mongodb://mongodatabse:secret#server/databaseOfUser1
//DB_URI_USER2=mongodb://mongodatabse:secret#server/databaseOfUser2
const user1Connection = mongoose.createConnection(process.env.DB_URI_USER1, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
const user2Connection = mongoose.createConnection(process.env.DB_URI_USER2, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
Then you create the model for each
const User1 = user1Connection.model(...)
const User2 = user2Connection.model(...)
Now on the API you query the desired model.
Working for me :)

Invalid scheme, expected connection string to start with "mongodb:" or "mongodb+srv://

Deploying my API then attempting to send a GET request to the DB results in Runtime.UnhandledPromiseRejection Invalid scheme, expected connection string to start with "mongodb:" or "mongodb+srv://
My db.js
import mongoose from "mongoose";
mongoose.Promise = global.Promise;
mongoose.set("strictQuery", false);
let connection_uri = process.env.MONGODB_URI;
let cachedMongoConn = null;
export const connectToDatabase = () => {
return new Promise((resolve, reject) => {
// mongoose.Promise = global.Promise;
mongoose.connection
.on("error", (error) => {
console.log("Error: connection to DB failed");
reject(error);
})
.on("close", () => {
console.log("Error: Connection to DB lost");
process.exit(1);
})
// Connected to DB
.once("open", () => {
// Display connection information
const infos = mongoose.connections;
infos.map((info) =>
console.log(`Connected to ${info.host}:${info.port}/${info.name}`)
);
// Return successful promise
resolve(cachedMongoConn);
});
if (!cachedMongoConn) {
cachedMongoConn = mongoose.connect(connection_uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
connectTimeoutMS: 60000,
bufferCommands: false,
});
} else {
console.log("MongoDB: using cached database instance");
resolve(cachedMongoConn);
}
});
};
.env
MONGODB_URI=mongodb+srv://Username:Password:...
Everything "looks" correct and the connection string in the .env file is in the right format. So I'm not sure what the issue is.
Any help you can provide would be greatly appreciated.

Unable to connect MongoDB server?

I have tried to connect to MongoDB server using the below-mentioned link but I am getting an error, I have entered the correct password and dbName but it couldn't connect. Can you please help me out?
const mongoose = require('mongoose');
mongoose.connect(`mongodb+srv://test:Test#123#cluster0.cvbne.mongodb.net/example?retryWrites=true&w=majority`,{userNewUrlParser : true, useUnifiedTopology: true},
err => {
if(!err)
console.log ("'mongoddb connection successed")
else
console.log ('Error white connecting mongodb : ' + JSON.stringify(err, undefined,2))
})
Use this instead:
mongoose.connect(`mongodb+srv://test:Test#123#cluster0.cvbne.mongodb.net/example?retryWrites=true&w=majority`), {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", () => console.log("---Connected to DB!---"));
To check if the connection is successful or not, you may use callback functions : on() and once().
const uri = MONGO_URI;
mongoose.connect(uri, { useNewUrlParser: true });
mongoose.connection.on(
'error',
console.error.bind(console, 'connection error: mongodb')
);
mongoose.connection.once('open', () => {
console.log(`mongodb at : ${uri}`);
});

Pass option { useUnifiedTopology: true } to the MongoClient constructor

Does anyone know why I'm still receiving a deprecation warning even though I've already specified useUnifiedTopoology: true in my MongoClient constructor?
Thank you in advance!
const mongodb = require('mongodb')
const MongoClient = mongodb.MongoClient
const connectionURL = 'connectionurl'
const databaseName = 'db'
const client = new MongoClient(connectionURL, { useNewUrlParser: true, useUnifiedTopology: true});
const insertHandler = async(data, collectionName) => {
await client.connect().then(async() => {
const collection = client.db(databaseName).collection(collectionName)
await collection.insertOne(data)
}).catch(error => {
console.log("Failed to insert:", error)
})
}
module.exports = {
insertHandler: insertHandler
}
And I'm getting the following error:
DeprecationWarning: current Server Discovery and Monitoring engine
is deprecated, and will be removed in a future version. To use the
new Server Discover and Monitoring engine, pass option { useUnifiedTopology:
true } to the MongoClient constructor.
You can do it this way
var mongoDb = require('mongodb');
var mongoClient = mongoDb.MongoClient;
var serverUrl = "mongodb://127.0.0.1:27017/";
var dbName = "sample_db";
mongoClient.connect(serverUrl, { useNewUrlParser: true, useUnifiedTopology: true }, function (err, db) {
// Code goes here...
});
I'm using Mongoose for MongoDB, the same code with no error. mongoose.connect("mongodb://localhost:27017/YOURDB", { useNewUrlParser: true, useUnifiedTopology: true });
mongoose.connect('mongodb://localhost/vidly',
{ useNewUrlParser: true , useUnifiedTopology: true })
.then(()=>{ return console.log("Connected to MongoDB Localhost...");
})
.catch(err => console.log("Could not connect",err))
It's working for me!!!
This is what I used and it worked for me:
const mongoServer = require('mongodb');
const mongoClient = mongoServer.MongoClient;
const dbName = 'tconnect';
const serverUrl = 'mongodb://localhost:27017/';
// Create a database
const dbUrl = serverUrl + dbName;
const client = new mongoClient(dbUrl, { useUnifiedTopology: true });
client.connect( (err, db) => {
if (err) {
console.log(err);
return;
}
else {
console.log('Database successfully created!');
db.close();
}
});
I tried it, and this is the solution which worked:
mongoose.connect("mongodb://localhost:27017/fruitsDB", { useNewUrlParser: true, useUnifiedTopology: true });
Kind regards,
I use it this way, and I don't see that warning anymore.
const run = async () => {
await mongoose.connect(keys.mongoURI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
};
run().catch(error => console.error(error);
https://github.com/Automattic/mongoose/issues/8169
this is the reference to solve this problem
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('debug', true);
const GITHUB_ISSUE = `gh8169`;
const connectionString = `mongodb://localhost:27017/${ GITHUB_ISSUE }`;
const { Schema } = mongoose;
run().then(() => console.log('done')).catch(error => console.error(error.stack));
async function run() {
console.log('Mongoose version:', mongoose.version);
mongoose.set('useUnifiedTopology', true);
mongoose.set('useNewUrlParser', true);
mongoose.connect(connectionString, { useFindAndModify: false });
const db = mongoose.connection;
db.once('open', () => console.log('connected'));
}
Write as below:
mongoose.connect('mongodb://localhost:27017/contactlist', { useNewUrlParser: true, useUnifiedTopology: true });

Why is my callback not working correctly?

This method runs at node server
const express = require("express");
const app = express();
const fs = require("fs");
const connectDb = require("./config/db");
const __init__ = (local = false) => {
fs.writeFile(
"./config/default.json",
`{
"mongoURI": ${
local
? `"mongodb://127.0.0.1:27017/test"`
: `"mongodb+srv://admin:<password>#abc-xxghh.mongodb.net/test?retryWrites=true&w=majority"`
}
}`,
function(err) {
if (err) {
return console.log(err);
}
connectDb();
}
);
};
__init__(true);
The problem is that if originally mongoURI: 127.0.0.1:27017, and if I do __init__(false), Node will try to connect to 127.0.0.1:27017, when it should be connecting to +srv uri.
If I run __init__(false) AGAIN, then it will connect to appropriate link.
Likewise, if I then run __init__(true), it will connect to srv+ when it should be connecting to local, and if I run __init__(true) again, only then it will connect to local.
What am I doing wrong here? I'm using the callback as Im supposed to, no?
Edit:
//config/db
// for mongoDB connection
const mongoose = require("mongoose");
// require the directory
const config = require("config");
// get all contents of JSON file
const db = config.get("mongoURI");
const connectDb = async () => {
try {
console.log("connecting to mongodb", db);
await mongoose.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true
});
console.log("Mongo DB connected");
} catch (err) {
console.log("unable to connect to mongodb");
console.log(err.message);
//exit if failure
process.exit(1);
}
};
module.exports = connectDb;
I've even tried doing the following:
.....
console.log("Developing locally:", local);
// require the directory
const config = require("config");
// get all contents of JSON file
const db = config.get("mongoURI");
connectDb(db);
.....
But it still reads the old value
The problem is on execution order since the require is sync
The order now is:
const connectDb = require("./config/db");
const config = require("config");
const db = config.get("mongoURI"); // this has the OLD VALUE
fs.writeFile(...
await mongoose.connect(db, { // this is using the OLD REFERENCE
So you need to change your connectDb function like this:
const connectDb = async () => {
const config = require("config");
// get all contents of JSON file
const db = config.get("mongoURI");
try {
console.log("connecting to mongodb", db);
await mongoose.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true
});
console.log("Mongo DB connected");
} catch (err) {
console.log("unable to connect to mongodb");
console.log(err.message);
//exit if failure
process.exit(1);
}
};
Anyway, I think this is not a nicer way to load config based on the environment, so I would suggest improving it using factory pattern.
Your code for URL local vs srv+ is correct. Problem i could see is placement of method connectDb();
fs.writeFile("fir arg - URL", "second -content", third - error fun {});
where in your code after function, connectDb() is placed after error fun. After it should be closed.

Categories