Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Publish certain information for Meteor.users and more information for Meteor.user

Tags:

meteor

I want to have client-side access for a certain set of fields for ALL users while I would like to have access to even more fields for the current user only. How do I go about writing publish code to accomplish this?

like image 394
HGandhi Avatar asked Oct 31 '12 05:10

HGandhi


People also ask

What is the meteor User () function for?

The Meteor Accounts system builds on top of the userId support in publish and methods . The core packages add the concept of user documents stored in the database, and additional packages add secure password authentication, integration with third party login services, and a pre-built user interface.

What is Meteor publish?

To publish records to clients, call Meteor. publish on the server with two parameters: the name of the record set, and a publish function that Meteor will call each time a client subscribes to the name. Publish functions can return a Collection.

Which of the following user accounts packages are provided by the meteor developer group?

Here's a complete list of login providers for which Meteor actively maintains core packages: Facebook with accounts-facebook. Google with accounts-google. GitHub with accounts-github.


3 Answers

Right from Meteor documentation:

Meteor.publish("userData", function () {
    return Meteor.users.find({_id: this.userId},
        {fields: {'other': 1, 'things': 1}});
});

And also:

Meteor.publish("allUserData", function () {
    return Meteor.users.find({}, {fields: {'nested.things': 1}});
});

Hope this helps.

like image 102
WispyCloud Avatar answered Oct 10 '22 00:10

WispyCloud


As mentioned above, the

Meteor.publish("userData", function () {
    return Meteor.users.find({_id: this.userId},
        {fields: {'other': 1, 'things': 1}});
});

and

Meteor.publish("allUserData", function () {
  return Meteor.users.find({}, {fields: {'nested.things': 1}});
});

publish functions will push the data from the Users collection.

Subscribe with

Tracker.autorun(function () {
    Meteor.subscribe("userData");
    Meteor.subscribe("allUserData");
});

And the additional data will automatically go into the Users collection and be available in the Meteor.user() object.

like image 42
Jesse Smith Avatar answered Oct 10 '22 02:10

Jesse Smith


My story with that: I proceeded as documentation says, but encountered with weird behavior. I had publish function, where I published whole profile and email object for current user (lets say userData) and just some subset for the other users (allUserData).

When I had -

Meteor.subscribe("allUserData");
Meteor.subscribe("userData");

On client side right after user logged in, I've received just allUserData data. Thats mean even for my logged in user (That user couldn't see his own email address). When I refresh browser, bug was fixed and I got properly allUserData for all users except one logged in, which has his proper userData (with mentioned email address).

What is interesting, if I changed the sequence of that subscriptions, bug was fixed.:

Meteor.subscribe("userData");    
Meteor.subscribe("allUserData");

Putting into Meteor.autosubscribe(function () { }) doesn't changed anything. Finally I tried put that subscription into Deps.autorun(function() { }) and explicitly add reactivity and the problem with sequence was resolved..:

Deps.autorun(function() {
  Meteor.subscribe("allUserData", Meteor.userId());
  Meteor.subscribe("userData", Meteor.userId());
  // or
  // Meteor.subscribe("userData", Meteor.userId());
  // Meteor.subscribe("allUserData", Meteor.userId());
}); 

In publish function I just replace this.userId with userId from parameter.

With next bug which I encountered was, that I've got secret systemData object in profile user's object and that can see just admins, not regular logged in users. But although correct set publish function with 'profile.systemData': 0 that secret object could see all logged in users which looked into his profile object. Probably it was because my publish function(s) somehow interfered with publish function in Meteor Account package:

// Publish the current user's record to the client.
Meteor.publish(null, function() {
 if (this.userId) {
   return Meteor.users.find(
     {_id: this.userId},
     {fields: {profile: 1, username: 1, emails: 1}});
 } else {
   return null;
 }
}, /*suppress autopublish warning*/{is_auto: true});

Anyway I resolved it with help of method Account.onCreateUser() and adding systemData next to profile object, not into profile. There starts my other problems :) see Meteor.loginWithPassword callback doesn't provide custom object in User accounts doc

PS: If I knew it at begin, I've put systemData object into special collection.

like image 5
jindrichb Avatar answered Oct 10 '22 01:10

jindrichb