A nodejs based server will archive user online-offline state and store all chat data. This will make client more light.
NOTE always set ts to current time when you push or set the data.
##Chat Apps with Firebase :
To create a chat, necessary firebase components :
- User - Handle real time online-offline status changes of user.
- Channel - Use to create chat room between two users
- Chat - Actual chat between users.
####USER
User url location is used to monitor online/offline status of users :
var userListRef = new Firebase('https://test-app.firebaseio.com/users');
#####Online When user online, push into the userListRef
{
id: "187154",
code_id: "TSDQWERY",
name: "Jhon",
gender : "Male",
filename_thumb : "thumb_68304308153044aad82a33.jpg"
on: 'connect' ,
status: "online",
ts: 1399880861,
}
ts
is current timestamp in epoch format when user online
#####Idle 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: "187154",
code_id: "TSDQWERY",
name: "Jhon",
gender : "Male",
filename_thumb : "thumb_68304308153044aad82a33.jpg",
on: 'connect' ,
status: "idle",
ts: 1399880861
}
ts
is current timestamp in epoch format when user idle
#####Away User is away if no activity in chat after 5 minutes from status idle, can be detected by timing the last time user tap, click or type something in screen, set current user ref into
{
id: "187154",
code_id: "TSDQWERY",
name: "Jhon",
gender : "Male",
filename_thumb : "thumb_68304308153044aad82a33.jpg",
on: 'connect' ,
status: "away",
ts: 1399880861
}
ts
is current timestamp in epoch format when user away
#####Offline
When app closed, tab closed (on browser) or refresh page. update userListRef on: "disconnect"
but user status still status : "online"
{
id: "187154",
code_id: "TSDQWERY",
name: "Jhon",
gender : "Male",
filename_thumb : "thumb_68304308153044aad82a33.jpg",
on: 'disconnect',
status: "online",
ts: 1399880861
}
For 10 second if user on:"disconnect"
not back online then Server will update userListRef status
to status: "offline"
. No action needed on client side.
{
id: "187154",
code_id: "TSDQWERY",
name: "Jhon",
gender : "Male",
filename_thumb : "thumb_68304308153044aad82a33.jpg",
on: 'disconnect',
status: "offline",
ts: 1399880861
}
#####Listing to Firebase event
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.
####CHANNEL
var userChannelListRef = new Firebase('https://test-app.firebaseio.com/channel');
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
.
When John
click Jane
chat button, we need create and push two reference :
var johnChannelRef = new Firebase('https://test-app.firebaseio.com/channel/John/Jane');
var janeChannelRef = new Firebase('https://test-app.firebaseio.com/channel/Jane/Jhon');
Push to johnChannelRef
:
{
box_chat: "open"
to: "Jane",
ts: 1396838766
}
And push to janeChannelRef
:
{
box_chat: "ready"
from: "Jhon",
ts: 1396838766
}
#####box_chat
Specific box_chat
property used for indicator chatbox on web with any position :
box_chat :"ready"
that means channel has create but chat box not yet open.box_chat :"open"
that means chat box open position so wherever the web page chat box still open.box_chat :"close"
that means chat box has close position.
####CHAT
Chat reference always formed by Channel reference, in case :
When John
want to talk with Jane
, The firebase ref would be:
var chatRef = new Firebase('https://test-app.firebaseio.com/chat/John-Jane);
We need to sort the string of the username involved, so it would be in correct order.
var part = ['John','Jane'].sort();
var chatRef = new Firebase('https://test-app.firebaseio.com/chat/'+ part[0] +'-' + part[1]);
Even though Jane
wants talk to John
keep using the same reference chatRef
that is always connected
for example John
Want to Chat with Jane
:
var chatRef = new Firebase('https://test-app.firebaseio.com/chat/Jhon-Jane)'
then push data to chatRef
:
{
filename_thumb: "thumb_68304308153044aad82a33.jpg",
from: "John",
to: "Jane",
message: "Hi !",
status: "read",
ts: 1396838766
}
and when Jane
want to chat with John
, then push with same reference chatRef
:
{
filename_thumb: "thumb_68304308153044aad82a33.jpg",
from: "Jane",
to: "John",
message: "yeah, how u doing ?",
status: "read",
ts: 1396838766
}
On process chating, if John send or push chat message to Jane we have to change channel Reference :
from -> to || to -> from
example : John chat to Jane, push this reference :
var ref = new Firebase('https://test-app.firebaseio.com/channel/John/Jane');
following data :
{
box_chat: "open"
to: "Jane",
ts: 1396838766
}
and if Jane chat with John, push this reference :
var ref = new Firebase('https://test-app.firebaseio.com/channel/Jane/John');
following data :
{
box_chat: "open"
from: "Jane",
ts: 1396838766
}
and continues like that, so we can use channel reference to take the last conversation from & to
any plunker examples?