How do you implement real-time listeners in Firestore?
Answer
Real-time listeners use onSnapshot() to receive data and live updates: (1) Document listener: const unsub = onSnapshot(doc(db, "chats", chatId), (snap) => { setMessages(snap.data()) }); (2) Collection listener: const unsub = onSnapshot(query(collection(db, "messages"), orderBy("timestamp"), limit(50)), (snap) => { snap.docChanges().forEach(change => { if (change.type === "added") addMessage(change.doc.data()); if (change.type === "modified") updateMessage(change.doc.id, change.doc.data()); if (change.type === "removed") removeMessage(change.doc.id); }); }); (3) Error handling: pass a second callback: onSnapshot(ref, onNext, onError); (4) Unsubscribe: the function returned by onSnapshot() unsubscribes when called. Always call it when the component unmounts (React: useEffect(() => { return unsub }, [])); (5) Metadata changes: onSnapshot(ref, { includeMetadataChanges: true }, handler) fires on local pending writes too. Listeners are charged as reads on the initial fetch and each change event.