Пользовательские поля в Meteor.users не публикуются

Моя конечная цель состоит в том, чтобы CUSTOM_FIELD_I_FREAKEN_WANT_TO_PUBLISH иметь доступ к шаблонам через {{currentUser}}, если они вошли в систему, но Meteor не отправляет все поля из коллекции пользователей.

В сервере:

Meteor.publish('userdata', function() {
    this.ready(); // do I really even need to do this?
    //return Meteor.users.find(); //This STILL doesn't work
    return Meteor.users.findOne({_id: this.userId});
});

В клиенте:

var s = Meteor.subscribe('userdata', function() { 
    console.log('userdata available');
    console.log('s.ready: '+s.ready())
});
console.log('s.ready: '+s.ready())

Я могу проверить, есть ли в коллекции поля, подключая непосредственно к экземпляру mongo и набрав: db.users.find():

{
    "_id" : "N2M7Zp265vkbTBTFF",
    "createdAt" : ISODate("2013-10-15T03:29:53.155Z"),
    "CUSTOM_FIELD_I_FREAKEN_WANT_TO_PUBLISH" : "P4GRrQMixEZducmuo",
    "profile" : {
        "name" : "Jonathan Dumaine",
            ...,
    },
    "services" : {
        "facebook" : {
            ....,
        }
    }
}

После проверки того, что подписка готова на клиенте, единственными полями в коллекции пользователей являются _id и _profile. Дополнительные поля не отображаются в клиенте (через консоль Meteor.users.find().fetch()) и не определяются при доступе через шаблоны.

Это ошибка? Я что-то делаю неправильно?

Ответ 1

Смотрите этот ответ:

 


По умолчанию сервер публикует имя пользователя, адрес электронной почты и профиль

Итак, вам нужно опубликовать/подписаться для дополнительных полей.

Сервер:

Meteor.publish('userData', function() {
  if(!this.userId) return null;
  return Meteor.users.find(this.userId, {fields: {
    permission: 1,
  }});
});

Клиент:

Deps.autorun(function(){
  Meteor.subscribe('userData');
});

 


 

Глядя на ваш код, недостающая часть - автозапуск по подписке. Без него подписка вызывается один раз, когда приложение загружается и не изменяется, когда пользователь меняет - когда он установлен в первый раз, например.

Ответ 2

Из docs:

По умолчанию текущее имя пользователя пользователя, электронные письма и профиль публикуются клиенту.

Итак, чтобы опубликовать ваше поле, вам нужно сделать что-то вроде:

Meteor.publish('userdata', function() {
  return Meteor.users.find({}, {fields: {'CUSTOM_FIELD_I_FREAKEN_WANT_TO_PUBLISH':1}});
});

Ответ 3

Ты был очень близок. У вас две проблемы:

1) Вызов ready() в публикации не нужен, поскольку он отправляется автоматически, если вы возвращаете курсор. Когда вам это нужно, вы хотите называть его в конце публикации после отправки всех данных.

2) Вы хотите вернуть курсор, который выполняется с помощью find() вместо findOne().

Итак, ваше опубликование будет:

//on server
Meteor.publish( 'userData', function(){
  return Meteor.users.find({_id: this.userId});
});

Показанный вами код фактически не проверяет, были ли получены какие-либо данные, чтобы убедиться, что это не проблема:

//on client
var s = Meteor.subscribe('userdata', function() { 
  console.log('userdata available');
  console.log('s.ready: '+s.ready());
  console.log('userData: ' + JSON.stringify( Meteor.users.findOne()) );
});

console.log('s.ready: '+s.ready())

Кроме того, как говорит Дэвид Уэлдон в своем ответе, вы, вероятно, захотите указать и ограничить то, какие поля будут отправляться клиенту, установив опцию полей в опубликованной вами статье find().

Ответ 4

Я думаю, вы, вероятно, пытались найти функцию Accounts.onCreateUser() из docs http://docs.meteor.com/#accounts_oncreateuser. Существует пример того, как добавить любой объект в пользовательский документ, рядом с профилем, электронной почтой, _id и т.д.