paint-brush
​​Easily Scale Real-Time Updates with Firestore: A Maintenance-Free Alternative to WebSocketsby@kingflamez
New Story

​​Easily Scale Real-Time Updates with Firestore: A Maintenance-Free Alternative to WebSockets

by Oluwole AdebiyiDecember 22nd, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

If you’re tired of managing WebSocket servers or stuck with inefficient polling for real-time updates, consider Firestore’s built-in listeners. Firestore scales automatically, requires almost no maintenance, and instantly pushes updates to your frontend. By using it as a relay layer over a MySQL database, you get global, low-latency real-time functionality—perfect for scenarios like live sports scores, Crypto price updates, etc—without the complexity of traditional solutions.
featured image - ​​Easily Scale Real-Time Updates with Firestore: A Maintenance-Free Alternative to WebSockets
Oluwole Adebiyi HackerNoon profile picture

​​​​Real-time features—instant score updates, live chat, or rapidly changing dashboards—are now a cornerstone of modern web applications. Traditionally, implementing these features has meant using WebSockets, long polling, or other solutions requiring meticulous scaling and maintenance. While WebSockets excel at real-time, bi-directional communication, managing their infrastructure at scale can be challenging and costly. Polling is simpler to implement but not truly real-time and can become inefficient as the number of clients grows.

​​This is where Firestore, a fully managed NoSQL database from Firebase, steps in as a simpler, highly scalable alternative that requires virtually no maintenance. Firestore’s built-in real-time listeners allow the frontend to receive updates whenever data changes without separate servers, clusters, or custom load balancers.


​​In this article, we’ll explore how leveraging Firestore for real-time updates lets you seamlessly scale your application. We will use a specific example—broadcasting live football scores—to demonstrate how Firestore can act as a "relay" for updates stored in your primary MySQL database. We’ll also provide a comprehensive comparison table of Firestore, WebSockets, and Polling, outlining their respective pros and cons to help you choose the best solution for your needs.

​​Comparing Firestore, WebSockets, and Polling: Pros and Cons

Feature

Firestore (Real-Time Listeners)

WebSockets

Polling

Setup Complexity

Very low; uses Firebase SDK and security rules (Firestore’s built-in access controls that let you define who can read or write specific data). No servers or load balancers to manage.

Moderate to high; requires dedicated servers or managed service and careful infrastructure setup.

Low; easy to implement using periodic HTTP requests, but can become inefficient at scale.

Scalability

Automatically managed by Google’s infrastructure; scales seamlessly as usage grows.

Requires manual scaling, load balancers, and monitoring as user counts increase.

Scales poorly as usage grows; increasing polling intervals can add unnecessary load.

Real-Time Updates

Near-instant updates with no extra logic required.

Provides true bi-directional, event-driven communication.

Limited “real-time”; updates depend on polling intervals, not instantaneous.

Latency

Low due to global distribution and built-in optimizations by Firestore.

Potentially low if infrastructure is well-optimized and globally distributed.

Higher latency, tied to polling frequency (e.g., every 5s or 10s), delays updates.

Maintenance

Minimal; no servers to patch or monitor. Automatic updates and scaling by Firestore.

Ongoing maintenance of servers, certificates, scaling strategies, and updates.

Minimal server logic, but may require adjustments and more servers as the user base grows.

Cost

Pay per read/write/storage. Efficiently handles large traffic without extra infrastructure.

Infrastructure and operational costs can grow significantly at large scale.

Potentially high server load and bandwidth costs due to frequent requests.

Global Reach

Built-in global distribution reduces latency for users worldwide.

Requires multiple regions or CDNs for global performance and low latency.

Similar to standard HTTP requests; relies on CDNs or multiple data centers for better performance.

Security

Use Firestore security rules and Firebase Auth to protect data at the document level.

Must handle TLS, authentication, and authorization logic on the server side.

Standard HTTPS-based security; still need to handle authentication and authorization externally.

Use Cases

Ideal for one-way or simplified real-time updates like live scores, dashboards, and IoT status updates.

Excellent for complex, bidirectional use cases like multiplayer gaming, live chats, or trading platforms.

Simple, good for low-frequency updates where true real-time is not critical, e.g. periodic weather updates.


In summary:

  • ​​Firestore simplifies implementation, scaling, and maintenance—great for quickly adding real-time updates to any app that needs to push state changes, like live scores or dashboards.
  • ​​WebSockets provide true, bidirectional communication and fine control, but require more effort and cost to scale and maintain.
  • ​​Polling is straightforward but not truly real-time and quickly becomes inefficient as the number of clients and required responsiveness grow.

​​How Firestore’s Real-Time Listeners Work

​​Firestore’s real-time listeners allow clients to subscribe to a document or collection. Whenever the underlying data changes, Firestore automatically pushes updates to all subscribed clients. This built-in feature lets you bypass manually implementing WebSockets, load balancers, and global infrastructure to achieve a highly responsive user experience.


​​Key Advantages of Firestore:

  • ​​Automatic Scaling: Firestore dynamically handles increased load and connections, no capacity planning or server provisioning required.
  • ​​Minimal Maintenance: No servers to patch, no certificates to renew, no complex load balancing. It reduces operational overhead to near zero.
  • ​​Global Reach: Firestore’s infrastructure spans the globe, ensuring low-latency reads and updates for users worldwide.

​​

​​Example: Broadcasting Live Football Scores

​​Imagine a scenario where you maintain your core data—team details, player stats, match progress—in a MySQL database. When a goal is scored, you update MySQL with the new score. You could then relay that updated state to the frontend in real-time via Firestore.


  1. ​​MySQL as the Source of Truth: Store and update canonical match data in MySQL, ensuring all historical and relational data remains intact.
  2. ​​Firestore as the Real-Time Relay: After updating MySQL, your backend posts a minimal snapshot (current score, time, status) to Firestore. Subscribers get the updated data instantly.
  3. ​​Frontend Integration: The frontend or mobile app (React, Vue, Angular, Android, iOS), listens to the Firestore document. Changes trigger a UI update, showing the latest score without page refreshes or manual intervention.

​​

​​  

​​

​​Setting Up Your Firestore Project

  1. ​​Create a Firebase Project:
  • ​​Go to the Firebase Console.
  • ​​Click Add project and follow the prompts.
  • ​​Once created, access your project’s dashboard.


​​  

​​

  1. ​​Enable Firestore:
  • ​​Navigate to Build > Firestore Database in the Firebase console.
  • ​​Click Create Database and choose a security mode and location.

​​

​​  

​​


  1. ​​Add Firebase to Your Web App:
  • In Project settings, under the General tab, add a new web app.
  • Follow the instructions to integrate the Firebase SDK into your frontend.

Full instructions: Add Firebase to your JavaScript project.


Data Model for Real-Time Updates

Keep the Firestore data minimal. For the football match, a single document might look like:

{

  "homeTeam": "Team A",

  "awayTeam": "Team B",

  "homeScore": 1,

  "awayScore": 2,

  "time": "89:00",

  "status": "LIVE"

}


Historical data and complex queries remain in MySQL, while Firestore holds just enough to keep the frontend in sync.


Backend Integration (Node.js Example)

After updating MySQL, mirror the update to Firestore:

const { Firestore } = require('@google-cloud/firestore');
const firestore = new Firestore();

async function updateScoreInMySQLAndNotify(homeScore, awayScore, matchId) {
    // Step 1: Update the MySQL database with the new score
    await mysqlClient.query(
        'UPDATE matches SET home_score = ?, away_score = ? WHERE id = ?',
        [homeScore, awayScore, matchId]
    );

    // Step 2: Retrieve the updated match data from MySQL
    const [rows] = await mysqlClient.query(
        'SELECT home_team, away_team, home_score, away_score, match_time, status FROM matches WHERE id = ?',
        [matchId]
    );

    const matchData = rows[0];

    // Step 3: Write minimal match data to Firestore for real-time updates
    await firestore.collection('matches').doc(String(matchId)).set({
        homeTeam: matchData.home_team,
        awayTeam: matchData.away_team,
        homeScore: matchData.home_score,
        awayScore: matchData.away_score,
        time: matchData.match_time,
        status: matchData.status
    });
}


Client-Side Integration

In your frontend:

import { initializeApp } from 'firebase/app';
import { getFirestore, doc, onSnapshot } from 'firebase/firestore';

// Your Firebase configuration
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
  projectId: "YOUR_PROJECT_ID",
};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

// Subscribe to a match document
const matchId = '123';
const unsubscribe = onSnapshot(doc(db, 'matches', matchId), (docSnapshot) => {
  if (docSnapshot.exists()) {
    const matchData = docSnapshot.data();
    updateScoreUI(matchData);
  } else {
    console.log("No such document!");
  }
});


When Firestore updates, the UI immediately reflects the new score—no page reloads or manual refreshes required.


Cost, Security, and Scalability Considerations

  • Costs: Firestore bills by reads, writes, and storage. Because you only write small documents when scores change and read them as events, costs scale smoothly. For example, if your app has 10,000 users and each user reads 5 updates per minute during a live match:
    • Reads per minute: 50,000
    • Reads per hour: 3,000,000, assuming Firestore charges $0.06 per 100,000 reads, so this would cost ~$1.80 for the hour.
    • For more information, visit Firestore Pricing.
  • Security Rules: Limit write access to your backend. All clients can read, but only authenticated backend processes should write to Firestore. Refer to: Firestore Security Rules.
  • Scalability Metrics: Firestore supports up to 1 million concurrent connections per database and can handle thousands of writes per second, making it suitable for high-traffic applications.


Example Security Rule:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /matches/{matchId} {
      allow read: if true; // Everyone can read
      allow write: if request.auth.token.admin == true; // Only admin or backend
    }
  }
}


Conclusion

Ready to scale real-time updates effortlessly? Start experimenting with Firestore today. By choosing Firestore’s real-time listeners over self-managed WebSockets or inefficient polling, you eliminate the complexity of scaling servers and maintaining infrastructure. Your team can spend more time perfecting the product and less on operational overhead. Whether broadcasting live football scores to millions of fans or updating a small dashboard, Firestore seamlessly scales, ensuring every user sees the latest data instantly.


With Firestore, real-time updates at scale become a worry-free reality—no stress in managing WebSocket servers or repetitive polling required.