DB query - am I doing this the right way?

Hey guys,

Total Meteor newb here, only been using it (and React) for about 10 days and loving them both so far!

Just want to check something before I go off on a tangent and code up my app the wrong way.

In one of my react components I’m making a db query before rendering the content to the screen. The component is rendered multiple times, each with it’s own set of user data (most of which will not belong to the logged in user). It’s all happening inside of constructor and it looks like this :

   if (this.props.track.owner) {
     this.owner = Meteor.users.findOne({_id: this.props.track.owner});
     this.displayName = this.owner.username;
   } else {
     this.displayName = this.props.track.owner

I’m using the owner prop (which is a valid user _id) passed into the component from the tracks collection to search the users collection for a matching _id and then grabbing the username and setting that to this.displayName which in turn is rendered as text to the screen.

Is this best practice for a simple db query like this?

I’m concerned that maybe this isn’t secure whatsoever as it’s all happening client side. Even though I’m only returning the username from this search, the entire user object is being returned before I select only the username. Would this potentially give anybody playing in the console access to the entire user object?

Its overkill for what you’re doing there.

The current user document is always available via Meteor.user(). No need to query the collection (the collection should only have that user record anyway)

You just need to watch out for the edge cases to avoid throwing errors. The component needs to handle things when the user doc isn’t available. So check for Meteor.userId() (returns false if no one is logged in) and Meteor.loggingIn() (temporary state while logging in)

— edit —

Regarding the user object and security - you control what is sent to the client. meteor will only send the logged in user their own user object so there is no security issue of your just using vanilla user accounts.

Thanks for the reply cstrat!

Sorry, I may have confused you when saying valid user _id before. It is a valid user _id but it’s more than likely not going to be the user ID of the current user - if that makes sense?

The current user model is going to be irrelevant 99.9% of the time with this specific component. This component renders pretty much the same if there is a logged in user or not. It’s only taking the current user into consideration if they happen to be looking at their own track, the rest of the time there will either be no current user models available to fulfil this query or just users that don’t have any ownership over the data this component spits out.

Unless you mean that all user models are available by default, regardless of who is actually logged in or not as the case may be?

Security wise, so even though this component is being rendered client side the user still can’t manipulate or traverse the user model? Sorry if I sound paranoid, coming from a PHP / Mysql background and still trying to find my feet with Mongo.

Hmmmm, okay just discovered something interesting.

I logged out and now I’m getting errors due to username being undefined. It seems like it was only working while I was logged in and setting the owner in the items in the tracks collection to the currently logged in user.

Now I’m logged out it’s not working.

So somehow the code I’ve written is only relative to the logged in user? Can you see where I’ve gone wrong? Maybe I’m just not grasping how this all works just yet?

Oh if that is the case then you’re much better off doing this via a Method call.
If you are trying to do it in the way you’ve written, you will need that user to be subscribed to get multiple users account records… this is not ideal.

Rather write a function in the component to fetchUser data, call that function (either when componentDidMount - or make it event driven from a form where a userID is entered).

Keeping that data controlled via method call is a much better practice - especially for user account data.

Yeah the reason that happened was by default a user is only subscribed to their own account records… so it would have worked for the logged in user. If not logged in then there is no data within Meteor.users on the client. Remember the server has ALL the data and the client only gets data to which it has subscribed.

1 Like