Build & Deploy a Real-Time Chat App with Firebase + Charts

 Build & Deploy a Real-Time Chat App with Firebase + Charts

If you’ve ever wanted to build your own real-time chat app and host it online for free — this guide is for you. We'll create a live chat app using Firebase Firestore and visualize messages using Chart.js, then deploy the app using Firebase Hosting.


🚀 What We'll Build

  • A simple real-time chat app (like WhatsApp lite 💬)

  • A bar chart showing how many messages are sent per hour

  • Realtime updates (no page refresh needed)

  • Live deployment with Firebase Hosting


🛠 Tech Stack

  • HTML + CSS + JavaScript

  • Firebase Firestore (for real-time DB)

  • Chart.js (for the message chart)

  • Firebase Hosting (for deployment)


🧱 Step 1: Firebase Project Setup

  1. Go to Firebase Console

  2. Click “Add project”

  3. Follow the prompts (you can skip Google Analytics)

  4. After it's created, click “</>” Add App (Web App)

  5. Copy your Firebase config object (we’ll need this)


📦 Step 2: Create the HTML App

Create a file named index.html and paste this code:

<!DOCTYPE html>
<html>
<head>
  <title>Firebase Chat with Chart</title>
  <style>
    body { font-family: sans-serif; max-width: 600px; margin: auto; padding: 20px; }
    #messages { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: scroll; margin-bottom: 10px; }
    .message { background: #f1f1f1; margin: 5px 0; padding: 6px 10px; border-radius: 4px; }
    #form { display: flex; gap: 10px; }
    input { flex: 1; padding: 10px; }
    button { padding: 10px 15px; background: #2196f3; color: white; border: none; cursor: pointer; }
    #chartContainer { margin-top: 30px; }
  </style>
</head>
<body>
  <h2>🔥 Firebase Chat</h2>
  <div id="messages"></div>

  <form id="form">
    <input type="text" id="messageInput" placeholder="Type your message..." required />
    <button type="submit">Send</button>
  </form>

  <div id="chartContainer">
    <h3>📊 Messages per Hour</h3>
    <canvas id="messageChart" width="400" height="200"></canvas>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>

  <script type="module">
    import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-app.js";
    import { getFirestore, collection, addDoc, onSnapshot, serverTimestamp, query, orderBy } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-firestore.js";

    const firebaseConfig = {
      apiKey: "YOUR_API_KEY",
      authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
      projectId: "YOUR_PROJECT_ID",
      storageBucket: "YOUR_PROJECT_ID.appspot.com",
      messagingSenderId: "YOUR_SENDER_ID",
      appId: "YOUR_APP_ID"
    };

    const app = initializeApp(firebaseConfig);
    const db = getFirestore(app);
    const messagesRef = collection(db, "messages");

    const messagesContainer = document.getElementById("messages");
    const form = document.getElementById("form");
    const input = document.getElementById("messageInput");

    const ctx = document.getElementById('messageChart').getContext('2d');
    let chart;
    const hours = Array.from({length: 24}, (_, i) => `${i}:00`);
    let messageCounts = new Array(24).fill(0);

    function updateChart() {
      if (chart) {
        chart.data.datasets[0].data = messageCounts;
        chart.update();
      } else {
        chart = new Chart(ctx, {
          type: 'bar',
          data: {
            labels: hours,
            datasets: [{
              label: 'Messages',
              data: messageCounts,
              backgroundColor: '#2196f3'
            }]
          },
          options: { scales: { y: { beginAtZero: true } } }
        });
      }
    }

    const q = query(messagesRef, orderBy("createdAt"));
    onSnapshot(q, (snapshot) => {
      messagesContainer.innerHTML = "";
      messageCounts = new Array(24).fill(0);
      snapshot.forEach(doc => {
        const msg = doc.data();
        const div = document.createElement("div");
        div.className = "message";
        div.textContent = msg.text;
        messagesContainer.appendChild(div);
        if (msg.createdAt?.toDate) {
          const date = msg.createdAt.toDate();
          messageCounts[date.getHours()]++;
        }
      });
      updateChart();
      messagesContainer.scrollTop = messagesContainer.scrollHeight;
    });

    form.addEventListener("submit", async (e) => {
      e.preventDefault();
      const text = input.value.trim();
      if (text) {
        await addDoc(messagesRef, {
          text,
          createdAt: serverTimestamp()
        });
        input.value = "";
      }
    });
  </script>
</body>
</html>

⚠️ Replace "YOUR_API_KEY" and other values with your Firebase config.


🚀 Step 3: Firebase Hosting (Deploy Live)

  1. Install Firebase CLI:

npm install -g firebase-tools
  1. Login:

firebase login
  1. Initialize:

firebase init
  • Choose Hosting

  • Choose your Firebase project

  • Set public as your directory

  • Say No to overwriting index.html

  1. Deploy:

firebase deploy

You’ll get a live URL like:

https://your-project-id.web.app

📸 Output Images

🔥 Chat App in Action

Here's what your live chat interface might look like


  • Users can send and receive messages in real time, no page reload required.

📊 Messages per Hour Chart

  • The chart dynamically updates as new messages are added, showing how many messages were sent during each hour of the day.


📁 Firebase Firestore Data

The Firestore part is critical here because we store and retrieve messages in real-time using Firebase's NoSQL database, Firestore. Here's how it works:

  1. Firestore Setup:

    • We set up a collection called messages where each document represents a single message.

    • Each document contains the text of the message and a createdAt timestamp.

  2. How Firestore Works in Real-Time:

    • Whenever a message is added to the collection, Firestore triggers a real-time update.

    • We use the onSnapshot method to listen to changes in the messages collection, so the UI automatically updates when a new message is added, without requiring a page refresh.

  3. Firestore Database Structure: Your Firestore database will look like this:

    • Collection: messages

      • Document: (each message document)

        • text: The content of the message

        • createdAt: A timestamp of when the message was sent

Here's how your Firestore database might look:


Each message document contains the text of the message and the createdAt timestamp, which we use to determine the hour the message was sent.


🎉 Done!

You’ve built and deployed a real-time chat app with live charting — all using Firebase and basic HTML. Fast, serverless, and scalable.


💡 Next Steps

  • Add Firebase Authentication (usernames, login)

  • Save user IDs

  • Add Storage for images/files

  • Style with Tailwind or frameworks like React

Want the code on GitHub? Let me know — I’ll push it for you!


🔗 Conclusion

By following this guide, you’ve not only learned how to use Firebase Firestore for real-time data syncing, but also how to visualize your app’s activity using Chart.js. Firebase Hosting made it easy to deploy your app to the web without worrying about servers. You’re ready to go live! 🚀

Comments