Blog>
Snippets

Real-time Synchronization with Firebase Firestore

Illustrate how to synchronize React component state with a Firebase Firestore document using useSyncExternalStore.
import React from 'react';
import { useSyncExternalStore } from 'react';
import { doc, onSnapshot } from 'firebase/firestore';
import { db } from './firebaseConfig'; // Ensure to import your Firebase config

export default function useFirestoreSync(documentPath) {
  // useSyncExternalStore expects to receive the current state of the store,
  // a function to subscribe to changes, and a function to get the snapshot
  return useSyncExternalStore(
    (listener) => {
      const docRef = doc(db, documentPath);
      const unsubscribe = onSnapshot(docRef, (doc) => {
        listener(doc.data());
      });
      return unsubscribe;
    },
    () => {
      const docRef = doc(db, documentPath);
      let state;
      const unsubscribe = onSnapshot(docRef, (doc) => {
        state = doc.data();
      });
      unsubscribe();
      return state;
    }
  );
}
This is a custom hook `useFirestoreSync` that uses `useSyncExternalStore` to sync a React component's state with a Firestore document. It takes a Firestore document path as input and returns the document's current state. A real-time subscription is created inside the hook, listening to the document's changes and updating the state accordingly. When the component unmounts, the listener unsubscribes to avoid memory leaks.
import React from 'react';
import useFirestoreSync from './useFirestoreSync';

function MyComponent() {
  const documentPath = 'collection/documentId'; // path to your Firestore document
  const documentData = useFirestoreSync(documentPath);

  return (
    <div>
      <pre>{JSON.stringify(documentData, null, 2)}</pre>
    </div>
  );
}

export default MyComponent;
This component `MyComponent` demonstrates the use of the `useFirestoreSync` hook. It defines the path to the Firestore document to be synced and uses the hook to keep the component's internal state in sync with the Firestore document in real-time. The state, which is the document data, is then rendered in a preformatted block.