2013-10-15 3 views
10

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

В сервере:

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()) 

я могу проверить, что есть поля в коллекции с помощью подключения к экземпляру Монго непосредственно и набрав: 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" : { 
      ...., 
     } 
    } 
} 

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

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

ответ

22

См this answer:

 


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

Поэтому вам необходимо опубликовать/подписаться на дополнительные поля.

Сервер:

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

Клиент:

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

 


 

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

+1

О, это очень хороший момент, но в этом случае он все равно не будет работать, потому что в функции публикации нет ничего реактивного, нет? Он должен быть переключен с помощью Meteor.user() вместо this.userId. И если реактивность находится внутри функции публикации, разве нет необходимости подписываться внутри автозапуска? : | –

+0

Я использую этот вид решения (который описан в официальных метеорных документах), и он хорошо работает для меня. Если вам необходимо обновить информацию о пользователе от клиента, вам нужно будет добавить Meteor.users.allow/deny – Rebolon

+1

Из документов «Однако, если пользователь вступил в систему, функция публикации повторно запускается с новым значением». Таким образом, этот ответ будет работать, но некоторая информация неточна. Публикация будет повторно запускаться всякий раз, когда пользователь изменяет, чтобы клиент получал новые данные. Публикация одной строки и однострочная подписка будут работать нормально. – user728291

8

Из docs:

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

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

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

Я понял, что строка в документах «имя пользователя, адрес электронной почты и профиль публикуются по умолчанию, поэтому любые дополнительные« publish'es будут публиковать остальные поля ». Я полагал, что '' userdata '' будет дополнять публикацию 'user' по умолчанию, поскольку она напрямую ссылается на Meteor.users. Разве это не так? –

+1

Кроме того, я пробовал это, и он все еще не работал. –

+0

Вы хотели бы удалить критерии поиска, которые ограничили публикацию данными текущего пользователя? – user728291

0

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

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()) 

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

Смежные вопросы