Real-time Updates

One of the most powerful features of Firebase is the ability to listen for real-time changes to your data. When a document changes on the server, all connected clients receive the update instantly.

1. Listening to a Document

Use the onSnapshot method to listen to a document.

import { db } from "../lib/firebase";
import { doc, onSnapshot } from "firebase/firestore";

const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => {
    console.log("Current data: ", doc.data());
});

// To stop listening:
// unsub();

2. Listening to a Collection

You can also listen to multiple documents in a collection using a query.

import { collection, query, where, onSnapshot } from "firebase/firestore";

const q = query(collection(db, "cities"), where("state", "==", "CA"));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
  const cities = [];
  querySnapshot.forEach((doc) => {
      cities.push(doc.data().name);
  });
  console.log("Current cities in CA: ", cities.join(", "));
});

3. Viewing Local Changes

Firestore provides "latency compensation." onSnapshot triggers immediately when you make a local change, before the data is even sent to the server.

onSnapshot(doc(db, "cities", "SF"), (doc) => {
  const source = doc.metadata.hasPendingWrites ? "Local" : "Server";
  console.log(source, " data: ", doc.data());
});
React Tip: In Next.js/React, always call unsubscribe() inside the useEffect cleanup function to avoid memory leaks.