"Not authorized on ___ to execute command" with mLab + MongoDB ^3.0 - mongodb

Connects without a hitch, but on insert() throws me this error.
var MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
var url = 'mongodb://____:____#ds125565.mlab.com:25565/heroku_w268n9pj';
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
db = client.db('temp');
console.log("connected!");
const collection = db.collection('temp');
collection.insert([{
something: please
}
});
I saw some other answers regarding mLab accounts and credentials, but I just created a new admin account for this. Frustrating because it was working previously with v2.3.

When attempting to connect to an mlab database, you have to correctly specify the client. It's located at the end of your connection string, just after the final forward slash.
mlab_url = "mongodb://db_user_name:db_password#ds139725.mlab.com:39725/heroku_sd1fp182?retryWrites=false"
client = MongoClient(url)
db = client["heroku_sd1fp182"]
collection = db["coinHack"]
You may also get the error:
This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.
Just add "?retryWrites=false" to your connection string, as shown above.

Related

Connecting to MongoDB from Vercel

I have a SvelteKit application deployed on vercel.app that uses a MongoDB (Atlas). In most cases the database connection works, but sometimes I get a connection error (connection timed out).
If this error occurs, and I try again to do something that uses the database, it immeadiately logs the same error again. This problem persists for some time, and then suddendly the database connection works again.
(When running the app locally with "npm run dev", using the same database, I've never experienced this error.)
To connect to the database, I defined:
mongodb-client.ts:
import { MongoClient } from 'mongodb';
const uri = process.env.DB_URI;
const dbClient = new MongoClient(uri).connect();
export default dbClient;
and use it like this (in several places):
import dbClient from '$lib/server/mongodb-client';
const user = await (await dbClient).db().collection('users').findOne({username: username});
I guess that, when the dbClient Promise is rejected (for whatever reason), it stays rejected and any subsequent await will immediately result in "rejected" (and therefore it will not try to reconnect; except that at some point it will ...?). Is my understanding correct? How should this be implemented correctly? (E.g. Do I need to add some options to the connection URI when this connection is create from a serverless function? Do I need to add some options when creating/connecting the MongoClient? Do I need to do this manually and add a loop, check if the promise is rejected and try again? Or should this be implemented in a completely different way?)
As you probably have guessed I'm new to JavaScript/TypeScript, MongoDB, Serverless and everything ... Thanks for any help and advice!
You can declare a function handling the connection to the database.
You will handle connection errors there and also check if a connection is already established:
import { MongoClient } from 'mongodb';
const uri = process.env.DB_URI;
const dbClient = new MongoClient(uri);
export const connectDb = async () => {
try {
if (!dbClient.isConnected()) {
await dbClient.connect();
}
return await dbClient.db();
} catch (e) {
console.log(e);
process.exit(1); // Or do something else...
}
};
Usage:
import { connectDb } from '$lib/server/mongodb-client';
const db = await connectDb();
const user = await db.collection('users').findOne({username: username});

Heroku Express + Postgres addon requires elevated privileges

[2018-05-16 08:27:12.979] [ERROR] server - Pipe
postgres://xnmcmqfirrdzkg:638d94fcd7aa5178e1054f0ff604613826033d5e8845fb42614c17a3d386823a#ec2-107-21-126-193.compute-1.amazonaws.com:5432/d5l5g60nk6l27a
requires elevated privileges
I'm trying to deploy server Express + Sequelize + Postgres on Heroku.
if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable]);
}
else {
config.logging = function (str) {
log4js.getLogger("sequelize").info(str);
}
var sequelize = new Sequelize(config.database, config.username, config.password, config);
}
The data's credential is set at default. I tried searching on the internet but there is no one having the same problem with me.
I am. But I have not been able to figure it out yet. And the docs I have been provided are more than two years old.

How to connect Mongolab with MongoDb.Driver

i'm testing mongolab with .netCore using MongoDb.Driver.
I have this connection string
mongodb://<dbuser>:<dbpassword>#mymongolaburl:46367/somedatabase
And i'm connecting this way
var connectionString = #"mongodb://<dbuser>:<dbpassword>#mymongolaburl:46367/somedatabase";
var databaseName = "somedatabase";
var client = new MongoClient(connectionString);
if (client != null)
{
_database = client.GetDatabase(databaseName);
_database.GetCollection<User>("User").InsertOne(new User {Name="Luke Skywalker" });
}
It is not working 'cause it says the database name is invalid, if i use the connection string without the database name
mongodb://<dbuser>:<dbpassword>#mymongolaburl:46367
I get a timeout execption.
I Already connected to database using Robo 3T.
Thanks in advance.
After one day i found how to do that in this link
The The solution is to specify which is database in the connection string
mongodb://<dbuser>:<dbpassword>#mymongolaburl:46367/?authSource=somedatabase
Thank you!

Module export of pg-promise object derived from promise chain

We're using HashiCorp's Vault to store database connection credentials, then constructing the connection string for pg-promise from those. The 'catch' is that the Vault details are provided from a Promise wrapper, due to request callbacks to the Vault API.
Example database.js module:
const pgp = require('pg-promise')(/* options obj */);
const getDbo = () => {
return new Promise( (resolve, reject) => {
vault.init().then(secrets => {
let credentials = secrets.dbUser + ':' + secrets.dbPass
let connStr = 'postgres://' + credentials + '<#endpoint/db>'
let dbo = pgp(connStr, (err) => {
reject(err)
})
resolve(dbo);
})
}
module.exports = { get: getDbo }
This is being imported in multiple routes. With this we are seeing the warning "WARNING: Creating a duplicate database object for the same connection." Is there a better way to resolve this so there is only one object per connection details?
Creating and initializing a connection for pg-promise is a completely synchronous operation, as per the API, so there is no point using promises for that.
For initializing the library see Where should I initialize pg-promise.
See also:
Verify database connection with pg-promise when starting an app.

Authenticating while connecting to multiple database using mongoose

I have set up auth in my MongoDB as mentioned here. Initially, in my project I was accessing a single database say, firstdb from mongoose using
let url = "mongodb://localhost:27017/firstdb";
let options = {
server:{
socketOptions:{
keepAlive:120
}
},
user:"username1",
pass:"mypassword1"
};
mongoose.connect(url,options,callback);
The user with username and mypassword was created in the firstdb itself giving it readWrite perms. I did this while logged in with my admin user.
Things were working smoothly. Then I had a requirement of connecting to a second database. So I changed my code as such
let url1 = "mongodb://localhost:27017/firstdb";
let options1 = {
server:{
socketOptions:{
keepAlive:120
}
},
user:"username1",
pass:"mypassword1",
auth:{
authdb:"firstdb"
}
};
let connection1 = mongoose.createConnection(url1,options1);
let url2 = "mongodb://localhost:27017/seconddb";
let options2 = {
server:{
socketOptions:{
keepAlive:120
}
},
user:"username2",
pass:"mypassword2",
auth:{
authdb:"seconddb"
}
};
let connection2 = mongoose.createConnection(url2,options2);
This time I created user username2 the same way in the seconddb database. But now mongoose is unable to perform any operation and is failing with Not authorized to execute command. I can access the db through mongo shell though. I also spun up the code in my local system which doesn't have mongodb auth enabled and it works fine there. Please help
So, after shooting around in the blind, found something that works.
Use the username and password in the url itself like
let connection1 = mongoose.createConnection("mongodb://username1:password1#localhost:27017/firstdb");
Still, I would like to know why passing the parameters as options doesn't work.