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

<%= @topic_view.topic.title %>
<%= @topic_view.topic.average_rating %> <%= @topic_view.topic.posts.count { |p| !!p.custom_fields['rating'] } %>

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);
        });
  }
});

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:[email protected]: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.

1 Like

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:[email protected]: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);
        })
    });

Just to clarify this good advice from cowboyLad, I still got the same ‘cannot do raw queries on admin in atlas’ when I wrapped my version 3.0 or later string.

So do NOT use version 3.0 when you are connecting to your atlas cluster. Use 2.2.12 or later, and then wrap it in quotes in your env file like cowboyLad suggested!

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…