Outline
Now that we have working channels with messaging, adding direct messages will be easier since we can reuse a lot of the existing functionality we have.
Messages
service, add a Firebase reference to the userMessages
node.
var userMessagesRef = firebase.database().ref('userMessages')
{x: add messages forusers}
Add a forUsers
function to our Messages
service to retrieve direct messages
between two users, given their uids.
return {
forChannel: function(channelId){
return $firebaseArray(channelMessagesRef.child(channelId));
},
forUsers: function(uid1, uid2){
var path = uid1 < uid2 ? uid1+'/'+uid2 : uid2+'/'+uid1;
return $firebaseArray(userMessagesRef.child(path));
}
};
We'll be storing our direct messages in Firebase like so:
{
"userMessages": {
"userid1": {
"userid2": {
"messageId1": {
"uid": "userid1",
"body": "Hello!",
"timestamp": firebase.database.ServerValue.TIMESTAMP
},
"messageId2": {
"uid": "userid2",
"body": "Hey!",
"timestamp": firebase.database.ServerValue.TIMESTAMP
}
}
}
}
}
Since we always want to reference the same path in our Firebase regardless of which id was passed first, we'll need to sort our ids before referencing the direct messages.
channels.direct
with the following code:
.state('channels.direct', {
url: '/{uid}/messages/direct',
templateUrl: 'channels/messages.html',
controller: 'MessagesCtrl as messagesCtrl',
resolve: {
messages: function($stateParams, Messages, profile){
return Messages.forUsers($stateParams.uid, profile.$id).$loaded();
},
channelName: function($stateParams, Users){
return Users.all.$loaded().then(function(){
return '@'+Users.getDisplayName($stateParams.uid);
});
}
}
});
This state is almost identical to channels.messages
, using the same
templateUrl
and controller
. We're using a different url
, and the
messages
dependency is using the Messages.forUsers
function that we just
created. The channelName
dependency also looks up the other user's display
name, and prefixes it with @
.
Users
service into ChannelsCtrl
users
on channelsCtrl
to Users.all
channelsCtrl.users = Users.all;
<div class="channel create">
<a ui-sref="channels.create">+ create channel</a>
</div>
<div class="list-head">Direct Messages</div>
<div class="channel" ng-repeat="user in channelsCtrl.users">
<a ng-if="user.$id !== channelsCtrl.profile.$id" ui-sref="channels.direct({uid: user.$id})" ui-sref-active="selected">
{{ user.displayName }}
</a>
</div>
We're now able to chat directly to other users in our application!
Check your work
You can view the completed & working code for this tutorial here: