MongoError: cannot do raw queries on admin in atlas for advanced node and express challenge

I get a MongoError: cannot do raw queries on admin in atlas for the Advanced Node and Express - Registration of New Users challenge when I try to register or login as a user and no data is displayed in my database. Would anybody know what is going on? I already changed the user access to read and write. It does say that database is connected. Please help.

server.js code:

'use strict';

const express     = require('express');
const bodyParser  = require('body-parser');
const fccTesting  = require('./freeCodeCamp/fcctesting.js');
/****my code****/
const session = require('express-session');
const passport = require('passport');
const ObjectID = require('mongodb').ObjectID;
const mongo = require('mongodb').MongoClient;
const LocalStrategy = require('passport-local');
/****my code****/
const app = express();
fccTesting(app); //For FCC testing purposes
app.use('/public', express.static(process.cwd() + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

/****my code****/
//set up template engine
app.set('view engine', 'pug');

//encrpyt cookie
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: true,
  saveUninitialized: true,
}));

//use passport init
app.use(passport.initialize());
//and passport session
app.use(passport.session());

//connect to db
mongo.connect(process.env.DATABASE, (err, db) => {
    if(err) {
        console.log('Database error: ' + err);
    } 
    else {
        console.log('Successful database connection');
      
        //serialization and app.listen
        //serialize id
        passport.serializeUser((user, done) => {
           done(null, user._id);
        });

        //deserialize without db
        passport.deserializeUser((id, done)=>{
          db.collection('users').findOne(
            {_id: new ObjectID(id)},
            (err, doc) => {
              done(null,doc);
            });
        });      
      
        //local strategy
        passport.use(new LocalStrategy(
          function(username, password, done) {
            db.collection('users').findOne({ username: username }, function (err, user) {
              console.log('User '+ username +' attempted to log in.');
              if (err) { return done(err); }
              if (!user) { return done(null, false); }
              if (password !== user.password) { return done(null, false); }
              return done(null, user);
            });
          }
        ));
            
        //ENSURE authenticated middleware for /profile link
        function ensureAuthenticated(req, res, next) {
          if (req.isAuthenticated()) {
              return next();
          }
          res.redirect('/');
        };      
      
        //index route
        app.route('/')
          .get((req, res) => {
            let homePageObjects = {
              title: 'Home Page',
              message: 'Please login',
              showLogin: true,
              showRegistration: true
            };
            res.render(process.cwd() + '/views/pug/index.pug', homePageObjects);
        });
      
        //authenticate user
        let authenticateUser = passport.authenticate('local', {failureRedirect: "/"});

        //login route
        app.route("/login")
          .post(authenticateUser,(req, res) => {
            res.redirect("/profile");
        });
           
        //profile route
        app.route('/profile')
          .get(ensureAuthenticated, (req, res) => {
            let profilePageObject = {
              username: req.user.username
            };
            res.render(process.cwd() + '/views/pug/profile', profilePageObject);
        });
 
        //register
        app.route('/register')
          .post((req, res, next) => {
              db.collection('users').findOne({ username: req.body.username }, function (err, user) {
                  if(err) {
                      next(err);
                  } else if (user) {
                      res.redirect('/');
                  } else {
                      db.collection('users').insertOne(
                        {username: req.body.username,
                         password: req.body.password},
                        (err, doc) => {
                            if(err) {
                                res.redirect('/');
                            } else {
                                next(null, user);
                            }
                        }
                      )
                  }
              })},
            //authenticate new user
            authenticateUser, (req, res, next) => {
                res.redirect('/profile');
            }
        );      
      
        //logout
        app.route('/logout')
          .get((req, res) => {
            req.logout();
            res.redirect('/');
        });
      
        //middleware for pages not found
        app.use((req, res, next) => {
          res.status(404)
            .type('text')
            .send('Not Found');
        });
        /****my code****/

        app.listen(process.env.PORT || 3000, () => {
          console.log("Listening on port " + process.env.PORT);
        });
  }
});
2 Likes

I was able to solve my own problem. Here is what I did.

  1. mongoDB Atlas -> connect: driver node.js, version: 2.2.12 or later-> copy connection string below.
  2. .env file on glitch-> make sure to wrap your string in quotations. Like this: DATABASE=‘mongodb://username:password@advancedzzsnodeclust-shard-00-00-ahytz.mongodb.net:27017,advancednodeclust-shard-00-01-ahytz.mongodb.net:27017,advancednodeclust-shard-00-02-ahytz.mongodb.net:27017/test?ssl=true&replicaSet=advancedNodeClust-shard-0&authSource=admin&retryWrites=true

Note: In version 3.0 or later it wasn’t important to wrap it in quotation but apparently in 2.2.12 it is. So keep that in mind.

11 Likes

hey cowboyLad I came across the same problem, I’m glad to see you came up with a solution but I’m confused I don’t understand the instructions you provided, especially step 1. would appreciate your response thanks.

Don’t worry its sorted now thanks a lot:

DATABASE='mongodb://username:password@cluster0-shard-00-00-f9l3z.mongodb.net:27017,cluster0-shard-00-01-f9l3z.mongodb.net:27017,cluster0-shard-00-02-f9l3z.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true'

I tested with mongodb it works fine, but there is a problem with mongoose which I can’t resolved it, anyone has idea?

Here is my code

    const connector = mongoose.connect(
        'mongodb+srv://<username>:<password>@cluster0-ppeaz.mongodb.net/sample_airbnb?retryWrites=true&w=majority&authSource=sample_airbnb'
    )
    .then(() => {
        const Listing = mongoose.model(
            'listingsAndReviews',
            new mongoose.Schema({
                name: String,
                summary: String,
            })
        );
        Listing.findOne({}).then((r) => {
            console.log(r);
        })
    });

The problem is with the login procedures…
After you log in to the database, you have to declare a constant:

const dbo = db.db("nameOfDatabase"); // the name is example: cluster0-l7rx6 

You find the name of database after your password followed by @
And any database query you have to use the dbo object instead of db.

dbo.collection("users").findOne(...);

Here is an example…

3 Likes

5 Likes

In the connection string, just change /admin over to your Database name. You don’t have to change the version.

This worked, thank you so much!
I realized my problem was that the Node.js driver was set on version 3 or later.

No idea why changing it to 2.2.12 solved the problem, but it worked!

Thanks a lot, this helped me out so much!

This is still required as of Jan 2020 to pass some of the tests in this module.

Thanks, it worked for me.

Thank you so much. I was having the same issue and i fixed it by using the solution you provided.