Right now all the chats are published to all the clients which is not very safe for privacy. Let's fix that.
First thing we need to do in order to stop all the automatic publication of information is to remove the autopublish
package from the Meteor server. Type in the command line:
$ meteor remove autopublish
We will add now the publish-composite package, which we will use later.
$ meteor add reywood:publish-composite
Now we need to explicitly define our publications. Let's start by sending the users' information.
Create a file named publications.js
under the server
folder and define the query we want to send to our clients:
1
2
3
4
5
import { Meteor } from 'meteor/meteor';
Meteor.publish('users', function() {
return Meteor.users.find({}, { fields: { profile: 1 } });
});
And of course we need to modify some of the client side code, we need to make sure that the client is subscribed to the published data, so let's do so in NewChatCtrl
, because this is where we need the users
data:
6
7
8
9
10
11
12
13
constructor() {
super(...arguments);
this.subscribe('users');
this.helpers({
users() {
return Meteor.users.find({ _id: { $ne: this.currentUserId } });
Now let's do a more complex publication, let's send each client only his chats with their messages.
In order to do that, we need to do a joined collections publication. reywood:publish-composite
package helps us achieve it with a very easy and convenient way.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Meteor } from 'meteor/meteor';
import { Chats, Messages } from '../lib/collections';
Meteor.publish('users', function() {
return Meteor.users.find({}, { fields: { profile: 1 } });
});
Meteor.publishComposite('chats', function() {
if (!this.userId) return;
return {
find() {
return Chats.find({ userIds: this.userId });
},
children: [
{
find(chat) {
return Messages.find({ chatId: chat._id });
}
},
{
find(chat) {
const query = { _id: { $in: chat.userIds } };
const options = { fields: { profile: 1 } };
return Meteor.users.find(query, options);
}
}
]
};
});
Now we will add a subscription to the chats
data in the client:
1
2
3
4
5
24
25
26
27
28
29
30
31
32
33
import { _ } from 'meteor/underscore';
import { Meteor } from 'meteor/meteor';
import { Config, Runner } from 'angular-ecmascript/module-helpers';
import chatsTemplateUrl from '../templates/chats.html';
...some lines skipped...
abstract: true,
templateUrl: tabsTemplateUrl,
resolve: {
user: this.isAuthorized,
chats() {
return Meteor.subscribe('chats');
}
}
})
.state('tab.chats', {