REALTIME WEB-BASED CHAT IN FIREBASE
Firebase provides the ability to use non-relational database which means data will be stored in objects and arrays. It uses JSON format to save data in database, the structure of data is similar to as stored in Mongo DB where each table is known as collection and each row is resembled with documents inside collection. By default, Firebase provides 15 GB of data where you can store text, images and documents too. One of the biggest advantage of using Firebase is that it has built-in support for realtime notifications which means that when a new item is added or removed it will automatically be notified in respective events. So Firebase ease the process of setting up Socket, Node JS and Mongo DB.
Goto Firebase Console and create a new project. Set the name of project and click “Continue”, you can disable the analytics for now. After that, click on “web” icon to integrate Javascript API in your project. Set the name of your project again and DO NOT set Firebase hosting because you will be running on your own localhost or hosting server. Then you will be displayed a code which you can copy and paste at the top of your project. In your firebase console, goto “Database” tab from left menu and click on “Realtime Database” and for now you can setup the database in test mode. The code you copied from Firebase console will only have firebase-app.js but you will also need firebase-database.js in order to use database. We will be using file named “index.php” where all chat operations are performed. Below code has some empty values but when you copy from Firebase console then they will be filled automatically as per your project.
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!-- The core Firebase JS SDK is always required and must be listed first --> <script src= "https://www.gstatic.com/firebasejs/6.6.1/firebase-app.js" ></script> <!-- include firebase database --> <script src= "https://www.gstatic.com/firebasejs/6.6.1/firebase-database.js" ></script> <script> // Your web app's Firebase configuration var firebaseConfig = { apiKey: "" , authDomain: "" , databaseURL: "" , projectId: "" , storageBucket: "" , messagingSenderId: "" , appId: "" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); </script> |
Sending message
Open your browser console by right click on empty area of page and select “Inspect Element” from context menu and open the “Console” tab. Make sure your internet is connected and check if there is any error. When it comes to sending message, for the sake of simplicity we will be saving username and message in the database. First we need to get the name of user when page opens, we can use Javascript built-in prompt() function to do that. Then we need to create a simple form with an input field to send message, when that form submits then we will call a function that will save the data in Firebase database. The autocomplete field will make sure not to display old entered values in this field. At the end of sendMessage() make sure to return false otherwise the form will submits to itself and the page refreshed. firebase.database() will return an instance of Firebase database, you can either store it in a separate variable to re-use it or you can call it every-time you need to perform some action in database. When the data is saved then Firebase will fire an event that will be called when a new child is added, we will discuss that in details in next step. The code below will create a new node named “messages” it will give it a unique ID and save username and message in it. The nodes in database are called as “Childs” in Firebase database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | < script > // Your web app's Firebase configuration var firebaseConfig = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); var myName = prompt("Enter your name"); </ script > <!-- create a form to send message --> < form onsubmit = "return sendMessage();" > < input id = "message" placeholder = "Enter message" autocomplete = "off" > < input type = "submit" > </ form > < script > function sendMessage() { // get message var message = document.getElementById("message").value; // save in database firebase.database().ref("messages").push().set({ "sender": myName, "message": message }); // prevent form from submitting return false; } </ script > |
Display messages
To display database data from Firebase we need to attach a listener called “child_added”. The main benefit of using this listener is that it simplifies the process of fetching the old messages from database, as well as to listen from new incoming messages. So this event will be called in 2 situations, when the page loads it will get all messages saved in database and second, when a new child is added in Firebase database. Code below will create a list where all messages needs to be displayed and attach a listener which will be called automatically when the page loads. On each iteration it will return a snapshot object which is a Firebase database object and it contains child’s key and value. On each iteration we are creating a new list and appending at the end of UL tag. As the child’s key is unique throughout the database, so we will be adding this as an ID to list item. This will be used when we try to delete message, it will be covered in detail in next step. We will be displaying delete button only if the message is sent from current user which means you can delete only those messages which are sent by you. Button tag will have an attribute data-id which will be used to get the unique ID of message and an onclick event is attached which will be called when that button is pressed. At the end we are displaying sender’s name and message content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <!-- create a list --> < ul id = "messages" ></ ul > < script > // listen for incoming messages firebase.database().ref("messages").on("child_added", function (snapshot) { var html = ""; // give each message a unique ID html += "< li id = 'message-" + snapshot.key + "' >"; // show delete button if message is sent by me if (snapshot.val().sender == myName) { html += "< button data-id = '" + snapshot.key + "' onclick = 'deleteMessage(this);' >"; html += "Delete"; html += "</ button >"; } html += snapshot.val().sender + ": " + snapshot.val().message; html += "</ li >"; document.getElementById("messages").innerHTML += html; }); </ script > |
Delete messages
Since we have already created a button to delete message, now we need to create a function that will be called when that button is pressed. We are going to delete the message from database and notify all other users that, that message has been removed. You can either remove that message node from list item or you can simply change the text of message to “This message has been removed” like WhatsApp does. Next time you refresh the page, that message will be removed altogether. First we are getting the unique ID of message from the data-id attribute of button. Then we call the remove() function of Firebase instance and it will remove that message child from database. As soon as the child is removed, Firebase has an event named “child_removed” which will be called with deleted child key and value. So we are attaching that listener which will return the deleted child key and value which can be used to remove or alter that node from list item. Now a delete button will be displayed along with your sent messages, when clicked it will be removed from Firebase database and a message will be displayed saying “This message has been removed”.
1 2 3 4 5 6 7 8 9 10 11 12 13 | function deleteMessage(self) { // get message ID var messageId = self.getAttribute( "data-id" ); // delete message firebase.database().ref( "messages" ).child(messageId).remove(); } // attach listener for delete message firebase.database().ref( "messages" ).on( "child_removed" , function (snapshot) { // remove message node document.getElementById( "message-" + snapshot.key).innerHTML = "This message has been removed" ; }); |
0 Comments