Skip to content

Instantly share code, notes, and snippets.

@arifsetiawan
Forked from khalifah86/Firebase Chat.md
Last active November 5, 2015 20:00
Show Gist options
  • Save arifsetiawan/d5dc9596af1192124b97 to your computer and use it in GitHub Desktop.
Save arifsetiawan/d5dc9596af1192124b97 to your computer and use it in GitHub Desktop.

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

@cyprusglobe
Copy link

any plunker examples?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment