Meteor.user() is not showing custom fields


#1

I am adding custom fields for my user on account creation, publishing the fields, and subscribing to that publication, and yet my Meteor.user().customField will not be accessible at the client side.

So in my imports/api/users/users.js I add the following snippet:

import { Random } from 'meteor/random'
// Generate user with our fields
Accounts.onCreateUser((options, user) => {
    const cond = assignUserCondition();
    user.enterTime= new Date();
    user.page = null;
    user.passedQuiz= false;
    user.exitStatus=null;
    user.quizAttempts= 0;
    user.condition= cond;
    user.avatar= null;
    user.score= 0;
    user.bonus= 0;
    user.lobbyTimeout= LOBBY_TIMEOUT;
    user.gameId= null;
    user.condInfo = {name: cond,
        groupSize: (cond+'GROUPS_SIZE').split('.').reduce((o, i) => o[i], CONDITIONS_SETTINGS),
        bonusConversion: (cond+'BONUS_CONVERSION').split('.').reduce((o, i) => o[i], CONDITIONS_SETTINGS),
        N_ROUNDS: (cond+'N_ROUNDS').split('.').reduce((o, i) => o[i], CONDITIONS_SETTINGS),
    };
    return user;
});

Then, from meteor mongo I verified that created users do have the new custom fields that I added. Now, in imports/api/users/server/publications.js I have the following snippet:

import {Meteor} from 'meteor/meteor'
Meteor.publish('users.user', function(currentUser) {
    let user=  Meteor.users.find({_id:currentUser}, {
        fields: {
            _id: 1,
            enterTime: 1,
            page: 1,
            passedQuiz: 1,
            exitStatus: 1,
            quizAttempts:1,
            condition:1,
            avatar: 1,
            score:1,
            bonus: 1,
            lobbyTimeout: 1,
            gameId: 1,
            conditionInfo: 1
        }
    });
    if ( user ) {
        return user;
    }
    return this.ready();
});

Also, in my imports/startup/client/index.js I have the subscription:

Tracker.autorun(function(){
    Meteor.subscribe('users.user');
});

However, on the client side, console.log(Meteor.user()) only shows the _id and username without my custom fields. What am I doing wrong here?


#2

You are not passing the currentUser in your subscription, so when the publish function runs it doesn’t find a user with _id=undefined.

But passing the user in as an argument is a security issue anyways, it means anyone could subscribe with an arbitrary userId and get someone else’s user record. You should change your publication to use this.userId

import {Meteor} from 'meteor/meteor'
Meteor.publish('users.user', function() {
    return Meteor.users.find(this.userId, {
        fields: {
            _id: 1,
            enterTime: 1,
            page: 1,
            passedQuiz: 1,
            exitStatus: 1,
            quizAttempts:1,
            condition:1,
            avatar: 1,
            score:1,
            bonus: 1,
            lobbyTimeout: 1,
            gameId: 1,
            conditionInfo: 1
        }
    });
});


#3

Yes this was the problem. Also, thanks for the advice on not passing userId around!