Let's Build a Firebase Chat App using Vanilla JavaScript

Subscribe to my newsletter and never miss my upcoming articles

Hello fellow coders! Today, we will be building a real-time messaging chat app using Firebase and vanilla JavaScript! There will be no frameworks used so it is perfect for beginners to follow along. First, let me start with Firebase 101.

Firebase 101

1.PNG Source: firebase.google.com

Firebase is a mobile and web development platform which is owned by Google since 2014. It has tons of products to help developers make apps faster with great quality. Some of its well-known products are the Firebase Authentication, Hosting, Cloud Functions and the one we will be using today, Real-time Database.

Step 1: Setting Up Firebase

  1. Head to https://firebase.google.com/ and if you haven't already, sign up for a Firebase account. Else, login to your Firebase console.

  2. Create a new project and name it whatever you want.

  3. Then on the dashboard, choose the "Web App" icon 1.PNG

  4. Get your firebaseConfig variables and store it somewhere. We will use it later.

Step 2: Setting Up HTML & CSS

  1. Create an index.html for your chat app's page.

  2. Add the <script src="https://www.gstatic.com/firebasejs/7.8.1/firebase-app.js"></script> line inside the <body> of your index.html

  3. Create the chat window, chat input and Send Message button with HTML and CSS.

    <div class = "chat">
         <div class = "chat-window" id = "chat-window">
           <ul id = "messages">
             <li class="msg">
               <span class = "msg-span">
                 <i class = "name">Host: </i>Hello and welcome to the chat!
               </span>
             </li>
           </ul>
           <form id = "messageForm" autocomplete="off">
             <input type = "text" id = "msg-input" placeholder="Enter a message">
             <button id = "msg-btn" type = "submit">Send</button>
           </form>
         </div>
    </div>
    

    The <div> class "chat" is the entire section where our chat app will be. The "chat-window" <div> contains our <ul> which is a list of individual messages inside a <li>. The <span> will contain the text of the message, with the <i> making the name of sender in bold. The <form> contains the <input> text field for the user to type a message and the Send <button> to send a message. Here's what it looks like:

2.PNG

As you can see in the HTML code and in the picture above, I've added a placeholder welcome message to see what an individual chat message <li class = "msg"> would look like on the window.

Differentiating User and Non-User's Messages

In chat apps, the user's messages are typically displayed on the right while the other party's messages will be on the left. So let's add a CSS class to distinguish between your messages and others' messages.

I added a "my" class which aligns the text to the right. If the <li> class is just "msg" then the text will be on the left and if it is "msg my", the text will display on the right like this:

3.PNG

<div class = "chat">
        <div class = "chat-window" id = "chat-window">
          <ul id = "messages">
            <li class="msg">
              <span class = "msg-span">
                <i class = "name">Host: </i>Hello and welcome to the chat!
              </span>
            </li>
            <li class="msg my">
              <span class = "msg-span">
                <i class = "name">Me: </i>My message is on the right
              </span>
            </li>
          </ul>
          <form id = "messageForm" autocomplete="off">
            <input type = "text" id = "msg-input" placeholder="Enter a message">
            <button id = "msg-btn" type = "submit">Send</button>
          </form>
        </div>
      </div>

You can find the full version of my custom css on my github here.

Step 3: Creating Database

Now that we've set up our HTML and CSS, let's work on Firebase and JavaScript.

Create an app.js file and add your firebaseConfig variables

const firebaseConfig = {
  apiKey: APP_API_KEY,
  authDomain: AUTH_DOMAIN,
  databaseURL: DATABASE_URL,
  projectId: PROJECT_ID,
  storageBucket: STORAGE_BUCKET,
  messagingSenderId: MESSAGING_SENDER_ID,
};

firebase.initializeApp(firebaseConfig);

Get the following DOM elements

const msgScreen = document.getElementById("messages"); //the <ul> that displays all the <li> msgs
const msgForm = document.getElementById("messageForm"); //the input form
const msgInput = document.getElementById("msg-input"); //the input element to write messages
const msgBtn = document.getElementById("msg-btn"); //the Send button

Initialise a database reference we will use to store our messages in and create a msgs folder

const db = firebase.database();
const msgRef = db.ref("/msgs"); 
//to store data in the msgs folder by creating a reference in database

Step 4: Send Messages to Database

Now that we have made a reference to our msgs folder in our Firebase database, we now can send messages and push it to the database in real-time. Firebase handles all the hard work for us. All we need to is to code a send message function on our Send button. Let's begin!

First, let's make the user give his/her name upon loading the app.

let name="";
function init() {
  name = prompt("Please enter your name");
}
document.addEventListener('DOMContentLoaded', init);

Explanation

DOMContentLoaded allows the init function to run as soon as the HTML page has rendered. The name variable is initialized as an empty string but once the init function runs, a prompt window will ask for the user's name and the name variable will be equal to the user's name.

Next, add an eventListener on our msgForm:

msgForm.addEventListener('submit', sendMessage);

In our sendMessage function, we have to check if our input text is not empty because why would we send a blank message? If it is not empty, we can create a message object which has the name of the user and the text he/she has written to store to the database. Then, we should clear our input field to prepare for the next message.

function sendMessage(e){
  e.preventDefault();
  const text = msgInput.value;

    if(!text.trim()) return alert('Please type a message'); //no msg submitted
    const msg = {
        name: name,
        text: text
    };

    msgRef.push(msg);
    msgInput.value = "";
}

We have not implemented the message to be updated on the page so don't panic if you don't see your message on screen after clicking "Send". You can test if your send button works by going to your Firebase dashboard, click on "Database" on the left panel and see your message appearing there in a folder called "msgs".

4.PNG

Step 5: Display/Update Messages on Screen

Now, we have to show our messages on the chat window so users can communicate with each other. We can create a simple updateMessage function for this.

First, we have to retrieve our messages data from our Firebase database. To do that, we can use a handy event from Firebase called "child_added". You can read more here.

5.PNG Source: firebase.google.com/docs/database/admin/ret..

The "child_added" event allows retrieval of data from the database then we can process the data in the callback function. It is triggered every time the database is updated. In our case, when we send a new message to our database.

For our purpose, we want to have this event ready when the page loads so that the chat window retrieves all our messages and display it on the chat window once the app starts. Which means we can add the following lines in our init() function:

msgRef.on('child_added', updateMsgs);

Then below the init() function, let's write the callback updateMsgs function:

const updateMsgs = data =>{
  const {dataName, text} = data.val(); //get name and text

  //load messages, display on left if not the user's name. Display on right if it is the user.
  const msg = `<li class="${dataName == name ? "msg my": "msg"}"><span class = "msg-span">
    <i class = "name">${name}: </i>${text}
    </span>
  </li>`

  msgScreen.innerHTML += msg; //add the <li> message to the chat window

  //auto scroll to bottom
  document.getElementById("chat-window").scrollTop = document.getElementById("chat-window").scrollHeight;
}

Code Explanation

In this function, we are essentially get our data in the same format as we store it, name and text. Then, we have to create our <li> message element to append it to our <ul> chat window element to display our message on screen.

In our <li>, we have to determine if the message will be displayed on the left or right. Remember that if the message is not written by the user, it will be displayed on the left with the class "msg". Else, display the message on the right with the class "msg my". We can do this by comparing the dataName we retrieved to the name of the user. As shown in the code above, I used a ternary if statement for efficiency and readability. And lastly, we shall insert our text inside the <span> element.

Then we add this entire <li> message to our chat window (i.e. msgScreen). As an optional final step, we can make sure the app will always display the latest messages by scrolling the window automatically to the bottom.

Let's Test!

At the end of this tutorial, you should have an app like this:

captured.gif

When the Send button is clicked, we send our message to the database. Our "child_added" event will trigger and call our updateMsgs function, which will immediately retrieve our message and display it on the chat window!

And that's it!

I hope this tutorial has been helpful for you to get started with Firebase and learning more about JavaScript in general. You can have lots of fun with making this chat app. For me, I created an encryption mode so that the words can look jumbled up. You can check out my chat app here.

Check out my gitHub repo for the full implementation code of my chat app: https://github.com/victoria-lo/Caht-Cfae

You can also integrate more Firebase products into this project just like how I used Firebase hosting and authentication in addition to the database. It can be good to learn. I encourage you to spend some time reading about Firebase from its documentation because it is a really helpful platform to use for apps.

Thanks for reading and have fun learning! Cheers!

P.S. : Thank you for all the support on this blog. Some of you have messaged me, wanting to connect through Twitter, so I rebooted my old Twitter account in case any of you would like to follow me on Twitter: twitter.com/lo_victoria2666

No Comments Yet