archiving will be handled in server, so no push to offline necessary. This will make client more light.
NOTE always set ts to current time when you push or set the data.
To create a chat, necessary firebase components :
User url location is used to monitor online-offline status of users
var userListRef = new Firebase('https://testsatu.firebaseio.com/users');
When user online, push into the userListRef
{
id: user-id,
ts: 1396838766,
name: user-name,
status: 'online'
}
ts
is current timestamp in epoch format.
when user is idle (there is no activity in chat after 5 minutes, can be detected by timing the last time user tap, click or type something in screen), set current user ref into
{
id: user-id,
ts: 1396838766,
name: user-name,
status: 'idle',
}
ts
is current timestamp in epoch format when user idle
If user back online, update again status in user ref, and add new item in changes
array
When user offline or disconnected or app closed, just remove reference from userListRef
Application only need to listen to userListRef
events.
- When
child_added
event received, add user to online list. - When
child_removed
event received, remove user from online user and update his status to offline. - When
child_update
event received, update user status to idle or online.
The case in mobile app might be different from website (where idle applied). As discussed, mobile app only has online or offline status.
- When app active, user is online
- When app goes to background or closed, user is offline.
Channel url is used to monitor who want to talk to specific user-id
from another-user-id
. Each user will have his/her own channel url. Data in channel is used to connect origin and destination in one chat ref
For example, lets say we have two users with id : John and Jane. John wants to chat to Jane.
John's channel ref
var userChannelListRef = new Firebase('https://testsatu.firebaseio.com/channel/John');
When John click Jane chat button. Push to John channel
{
to: Jane,
ts: 1396838766
}
Then push to Jane channel
var targetChannelListRef = new Firebase('https://testsatu.firebaseio.com/channel/Jane');
following data
{
from: John,
ts: 1396838766
}
Then create new chat ref for John-Jane
var chatRef = new Firebase('https://testsatu.firebaseio.com/chat/John-Jane);
Jane's channel ref
var userChannelListRef = new Firebase('https://testsatu.firebaseio.com/channel/Jane');
- When
child_added
event received, create new chat ref for John-Jane usingfrom
field in the data.
var chatRef = new Firebase('https://testsatu.firebaseio.com/chat/John-Jane);
Now John and Jane is ready to chat.
When chat window is closed, remove current channel from destination channel ref. In above example, remove from Jane's channel ref, data which come from John. And in John channel ref, remove his intention to chat to
Previously, we use channel as global ref for all users to listen. If global, then we need to filter users who are not intended to chat to. So now, user will have his/her own channel.
Now both John and Jane are using the same chat ref
var chatRef = new Firebase('https://testsatu.firebaseio.com/chat/John-Jane);
it is simple matter to push new chat and listen to the event when child_added
Push following data for every chat
{
from: 'John',
ts: 1396838766,
message: 'Hi, how are you?',
}
Because the way firebase works, when user chat to other user and both had done some chatting before, previous chat will be shown.