Meteor.user with Additional Fields on Client

504 Views Asked by At

In Meteor, one can add additional fields to the root-level of the new user document like so:

// See: https://guide.meteor.com/accounts.html#adding-fields-on-registration
Accounts.onCreateUser((options, user) => 
  // Add custom field to user document...
  user.customField = "custom data";

  return user;
});

On the client, one can retrieve some data about the current user like so:

// { _id: "...", emails: [...] }
Meteor.user()

By default, the customField does not exist on the returned user. How can one retrieve that additional field via the Meteor.user() call such that we get { _id: "...", emails: [...], customField: "..." }? At present, the documentation on publishing custom data appears to suggest publishing an additional collection. This is undesired for reasons of overhead in code and traffic. Can one override the default fields for Meteor.user() calls to provide additional fields?

2

There are 2 best solutions below

5
Kelly Copley On BEST ANSWER

You have a couple of solutions that you can use to solve this.

  1. Null Publication
Meteor.publish(null, function () {
  if (this.userId !== null) {
    return Meteor.users.find({ _id: this.userId }, { fields: { customField: 1 } });
  } else {
    return this.ready();
  }
}, { is_auto: true });

This will give you the desired result but will also result in an additional database lookup.. While this is don't by _id and is extremely efficient, I still find this to be an unnecessary overhead.

2.Updating the fields the Meteor publishes for the user by default.

Accounts._defaultPublishFields.projection = { customField: 1, ...Accounts._defaultPublishFields.projection };

This has to be ran outside of any Meteor.startup blocks. If ran within one, this will not work. This method will not result in extra calls to your database and is my preferred method of accomplishing this.

2
Christian Fritz On

You are actually misunderstanding the documentation. It is not suggesting to populate and publish a separate collection, just a separate publication. That's different. You can have multiple publications/subscriptions that all feed the same collection. So all you need to do is:

Server:

Meteor.publish('my-custom-user-data', function() {
  return Meteor.users.find(this.userId, {fields: {customField: 1}});
});

Client:

Meteor.subscribe('my-custom-user-data');