How to retrieve currentUser data with Vue.js, AWS Amplify, and MongoDB

ghz 1years ago ⋅ 4584 views

Question

I am attempting to build a Vue.js App that synthesizes properties of AWS, MongoDB, and Express. I built an authentication page for the app using aws- amplify and aws-amplify-vue. After logging into the app, metadata containing the username for the logged in AWS user is passed into data object property this.name like so:

  async beforeCreate() {
    let name = await Auth.currentAuthenticatedUser()
    this.name = name.username
  }

this.name is then added to MongoDB via Axios:

    async addName() {
        let uri = 'http://localhost:4000/messages/add';
        await this.axios.post(uri, {
          name: this.name,
        })
        this.getMessage()
      } 

I also have a getName() method that I am using to retrieve that data from MongoDB:

    async getData () {
      let uri = 'http://localhost:4000/messages';
      this.axios.get(uri).then(response => {
        this.userData = response.data;
      });
    },

This method, however, returns data for ALL users. I want to reconfigure this method to ONLY return data for .currentAuthenticatedUser(). In my previous experience with Firebase, I would set up my .getData() method with something like:

let ref = db.collection('users')
let snapshot = await ref.where('user_id', '==', firebase.auth().currentUser.uid).get()

...in order to return currentUser information on the condition that 'user_id' in the collection matches the currently logged-in Firebase user.

To achieve this with MongoDB, I attempted to configure the above method like so:

    async getData () {
      let uri = 'http://localhost:4000/messages';
      let snapshot = await uri.where('name', '==', this.name);
      this.axios.get(snapshot).then(response => {
        this.userData = response.data;
      });
    },

My thought here was to try and return current user data by comparing 'name' in the MongoDB collection with the logged-in user stored in this.name...but I understand that this might not work because the .where() method is probably unique to Firebase. Any recommendations on how to configure this .getData() to return ONLY data associated with the currentAuthenticatedUser? Thanks!

EXPRESS ROUTES:

const express = require('express');
const postRoutes = express.Router();

// Require Post model in our routes module
let Post = require('./post.model');

// Defined store route
postRoutes.route('/add').post(function (req, res) {
  let post = new Post(req.body);
  post.save()
    .then(() => {
      res.status(200).json({'business': 'business in added successfully'});
    })
    .catch(() => {
      res.status(400).send("unable to save to database");
    });
});

// Defined get data(index or listing) route
postRoutes.route('/').get(function (req, res) {
    Post.find(function(err, posts){
    if(err){
      res.json(err);
    }
    else {
      res.json(posts);
    }
  });
});

module.exports = postRoutes;

Answer

It is not possible to apply a where clause to a uri AFAIK. What you should do is adding a where clause to the actual query you are making in your backend and, to do that, send the username you want to filter the query with through a query parameter like this: /messages?name=JohnDoe.

So basically if you are using a Node/Express backend, as you suggested, and using Mongoose as the ODM for MongoDB your request would probably be looking something like this:

const Users = require('../models/users.model');

Users.find({}, function (e, users) {
    if (e) {
        return res.status(500).json({
            'error': e
        })
    }

    res.status(200).json({
        'data': users
    });
})

What you should do is getting the username query parameter through req.query and add it to the options in the first parameter of the find function.

const Users = require('../models/users.model');

let params = {},
    name = req.query.name;

if (name) {
    params.name = name
}

Users.find(params, function (e, users) {
    if (e) {
        return res.status(500).json({
            'error': e
        })
    }

    res.status(200).json({
        'data': users.slice
    });
})

That way if you point to /messages?name=John you will get the users with "John" as their name.

Edit :

If your backend is configured in the following way

postRoutes.route('/').get(function (req, res) {
    Post.find(function(err, posts){
    if(err){
      res.json(err);
    }
    else {
      res.json(posts);
    }
  });
});

what you should do is get the query parameters from inside the get method

postRoutes.route('/').get(function (req, res) {
    let params = {},
        name = req.query.name

    if (name) {
       params.name = name
    }

    Post.find(params, function(err, posts){
    if(err){
      res.json(err);
    }
    else {
      res.json(posts);
    }
  });
});