Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to manage Chat channels in Firebase

In my main page I have a list of users and i'd like to choose and open a channel to chat with one of them.

I am thinking if use the id is the best way and control an access of a channel like USERID1-USERID2.

But of course, user 2 can open the same channel too, so I'd like to find something more easy to control.

Please, if you want to help me, give me an example in javascript using a firebase url/array.

Thank you!

like image 956
Eusthace Avatar asked Nov 05 '15 09:11

Eusthace


People also ask

Is firebase good for chat app?

Yes, in that it's easy to build a chat app on Firebase, and it's a really good showcase for the capabilities of real-time messaging and notifications. There's a reason it's one of the apps in the codelabs.


2 Answers

A common way to handle such 1:1 chat rooms is to generate the room URL based on the user ids. As you already mention, a problem with this is that either user can initiate the chat and in both cases they should end up in the same room.

You can solve this by ordering the user ids lexicographically in the compound key. For example with user names, instead of ids:

var user1 = "Frank"; // UID of user 1 var user2 = "Eusthace"; // UID of user 2  var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);  console.log(user1+', '+user2+' => '+ roomName);              user1 = "Eusthace"; user2 = "Frank";  var roomName = 'chat_'+(user1<user2 ? user1+'_'+user2 : user2+'_'+user1);  console.log(user1+', '+user2+' => '+ roomName);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

A common follow-up questions seems to be how to show a list of chat rooms for the current user. The above code does not address that. As is common in NoSQL databases, you need to augment your data model to allow this use-case. If you want to show a list of chat rooms for the current user, you should model your data to allow that. The easiest way to do this is to add a list of chat rooms for each user to the data model:

"userChatrooms" : {   "Frank" : {     "Eusthace_Frank": true   },   "Eusthace" : {     "Eusthace_Frank": true   } } 

If you're worried about the length of the keys, you can consider using a hash codes of the combined UIDs instead of the full UIDs.


This last JSON structure above then also helps to secure access to the room, as you can write your security rules to only allow users access for whom the room is listed under their userChatrooms node:

{   "rules": {     "chatrooms": {       "$chatroomid": {         ".read": "            root.child('userChatrooms').child(auth.uid).child(chatroomid).exists()         "       }     }   } } 
like image 141
Frank van Puffelen Avatar answered Sep 21 '22 22:09

Frank van Puffelen


In a typical database schema each Channel / ChatGroup has its own node with unique $key (created by Firebase). It shouldn't matter which user opened the channel first but once the node (& corresponding $key) is created, you can just use that as channel id.

Hashing / MD5 strategy of course is other way to do it but then you also have to store that "route" info as well as $key on the same node - which is duplication IMO (unless Im missing something).

like image 28
Neo Split Avatar answered Sep 18 '22 22:09

Neo Split