Search code examples
javascriptreactjsfirebasefirebase-toolsreactfire

How to use firestore emulator with reactfire?


I have set up firestore locally following the firebase docs and I can test firebase functions easily. I would love to develop locally with an local firestore database. In the docs they provide the following code:

// Initialize your Web app as described in the Get started for Web
// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
  db.settings({
    host: "localhost:8080",
    ssl: false
  });
}

How can I do this, if I use reactfire with reactjs to init firebase? Currently its initialised like this:

const firebaseConfig = {
  apiKey: "",
  authDomain: "example.firebaseapp.com",
  databaseURL: "https://example.firebaseio.com",
  projectId: "example",
  storageBucket: "example.appspot.com",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
};

ReactDOM.render(
  <React.StrictMode>
    <FirebaseAppProvider firebaseConfig={firebaseConfig}>
      <App/>
    </FirebaseAppProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

Should I just manipulate the databaseURL: in the config or is there another best practice to connect to the local emulator firestore?


Solution

  • I have found an Github Issue in which its suggested to use preloadFirestore from reactfire.

    They although provide an example in their sample app:

    preloadFirestore(firebaseApp, firestore => { 
      return firestore().enablePersistence(); 
    }), 
    

    If you want to use it like they do, you have a basic setup like this:

    // create a preload function to combine multiple preloads
    const preloadSDKs = firebaseApp => {
      return Promise.all([
        preloadFirestore(firebaseApp, firestore => {
          return firestore().settings({host: 'localhost:8080', ssl: false});
        }),
        // preloadDatabase(), 
        // preloadStorage(), 
        // etc.
      ]);
    };
    
    function App() {
      const firebaseApp = useFirebaseApp();
    
      // Kick off fetches for SDKs and data that
      // we know our components will eventually need.
      //
      // This is OPTIONAL but encouraged as part of the render-as-you-fetch pattern
      // https://reactjs.org/docs/concurrent-mode-suspense.html#approach-3-render-as-you-fetch-using-suspense
      preloadSDKs(firebaseApp).then(() => Promise.resolve());
    
      return (
        <YourComponents />
      )
    }
    

    Afterwards you can just use useFirestore() anywhere in the app to lazy load it with the settings above.

    Hints:

    • You have to use the <FirebaseAppProvider /> before preloading the SDKs
    • Your component preloading the SDKs has to be wrapped inside a <Suspense /> or <SuspenseWithPerf /> component
    • Check the reactfire demo app to see how you can not only preload SDKs but data as well