如何将 firestore 模拟器与 reactfire 一起使用?

How to use firestore emulator with reactfire?

我已经按照 firebase docs 在本地设置了 firestore,我可以轻松测试 firebase 功能。我很乐意使用本地 firestore 数据库在本地进行开发。在文档中,他们提供了以下代码:

// 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
  });
}

如果我使用 reactfire 和 reactjs 来初始化 firebase,我该怎么做?目前它的初始化是这样的:

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")
);

我应该只在配置中操作 databaseURL: 还是有其他连接到本地模拟器 firestore 的最佳实践?

我找到了一个 Github Issue,其中建议使用来自 reactfire 的 preloadFirestore

尽管他们在 their sample app 中提供了示例:

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

如果你想像他们一样使用它,你有一个像这样的基本设置:

// 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 />
  )
}

之后,您可以在应用中的任何地方使用 useFirestore() 来延迟加载上面的设置。

提示:

  • 您必须在预加载 SDK 之前使用 <FirebaseAppProvider />
  • 预加载 SDK 的组件必须包装在 <Suspense /><SuspenseWithPerf /> 组件中
  • 查看 reactfire demo app 了解如何不仅可以预加载 SDK,还可以预加载数据

感谢你们的帮助! Reactfire api 再次更改,这是当前有效的解决方案:


import React from 'react';
import logo from './logo.svg';
import './App.css';
import Answers from './components/answers'
import HomeScreen from './screens/HomeScreen'
import { preloadFirestore, useFirebaseApp } from 'reactfire'
import firebase from 'firebase'

const preloadSDKs = (firebaseApp: firebase.app.App) => {
  return Promise.all([
    preloadFirestore({
      firebaseApp,
      setup: firestore => {
      return firestore().settings({host: 'localhost:8080', ssl: false});
    }
    }),
    // preloadDatabase(),
    // preloadStorage(),
    // etc.
  ]);
};

function App() {
  const firebaseApp = useFirebaseApp();

  preloadSDKs(firebaseApp).then(() => Promise.resolve());

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <HomeScreen />
      </header>
    </div>
  );
}

export default App;

Reactfire docs on emulation现在与之前的答案中提到的不同,它们已于 2021 年 8 月更新。

我修改了他们的示例,向您展示如何将 firestore 和 auth 模拟器与 Firebase v9+:

一起使用
import { getAuth, connectAuthEmulator } from 'firebase/auth'; // Firebase v9+
import { getFirestore, connectFirestoreEmulator } from 'firebase/firestore'; // Firebase v9+

import { FirebaseAppProvider, DatabaseProvider, AuthProvider, useFirebaseApp } from 'reactfire';

function FirebaseComponents({ children }) {
  const app = useFirebaseApp();
  const firestore = getFirestore(app);
  const auth = getAuth(app);

  // Check for dev/test mode however your app tracks that.
  // `process.env.NODE_ENV` is a common React pattern
  if (process.env.NODE_ENV !== 'production') {
    // Set up emulators
    connectFirestoreEmulator(firestore, 'localhost', 8080);
    connectAuthEmulator(auth, 'http://localhost:9099');
  }

  return (
    <AuthProvider sdk={auth}>
      <FirestoreProvider sdk={firestore}>
        <MyCoolAppThatUsesAuthAndFirestore />
      </FirestoreProvider>
    </AuthProvider>
  );
}

其他模拟器也存在类似的连接模式(connectStorageEmulatorconnectDatabaseEmulator 等...)