如何在 reactfire 上启用持久性?

IT技术 javascript reactjs firebase google-cloud-firestore reactfire
2021-04-28 01:05:04

我想使用reactfire在我的 PWA React 应用程序上实现 Firestore 离线持久性

const firestore = useFirestore().enablePersistence();

  let documentReference = firestore
    .collection("food")
    .doc("milkshake");

  const { data } = useFirestoreDocData(documentReference);

但是运行代码我得到一个错误:

FirebaseError:Firestore 已启动,无法再启用持久性。您只能在对 Firestore 对象调用任何其他方法之前启用持久性。

<Suspense>如文档中所述,该组件被包裹在 a

该数据库读取是我在整个应用程序中所做的唯一一个,我该如何解决?

编辑。

使用@Ajordat 给出的示例,我preloadFirestore在 App 组件中导入了该函数,但出现错误:

“无法读取未定义的属性‘名称’”。

而适应(因为我不能在 fetch 函数中使用钩子)来自@DougStevenson 的例子:我已经useFirestoreApp组件中导入了函数(为了获取 Firestore 对象)以启用持久性,然后将它 ( useFirestore) 导入到我的组件中为了检索数据,但现在,我收到与以前相同的错误,

Firestore 已启动,无法再启用持久性。

编辑2:

我已经尝试无错误地启用Persistence,谢谢大家,这是我的方法,如果它是最好的,请告诉我:

const firestore = useFirestore();

  React.useEffect(() => {
    firestore.enablePersistence();
  }, []);

在我的自定义组件中:

let docRef = useFirestore()
    .collection("food")
    .doc("milkshake");

  let document = useFirestoreDocDataOnce(docRef);
  console.log(document)

但是现在我确实遇到了一个问题,当我记录文档时,数据不会立即发出,是的,我知道这是一个异步操作,但是组件被包裹在 a 中<Suspense>,以这种方式:

<Suspense fallback={<div>Loading</div>}>
  <FoodComponent foodName={"Milkshake"} />
</Suspense>

但是在实际渲染组件之前我没有看到加载文本。

悬念片段是否仅在加载函数(useFirestore)而不是实际数据时显示回退组件?

好吧,我已经解决了,必须解构数据,这样做:

let docRef = useFirestore()
    .collection("food")
    .doc("milkshake");

  let { data: document } = useFirestoreDocData(docRef);
  console.log(document)
2个回答

在 Firestore 的其他 JavaScript 库中,enablePersistence()返回一个Promise。这意味着它将在未来的某个时间完成,无法保证需要多长时间。如果您在调用 enablePersistence() 后立即执行查询,而不等待返回的Promise完成,那么您将看到此错误消息。那是因为查询“击败”了持久层并有效地首先执行。

您将必须弄清楚如何使用该Promise来等待,直到可以在启用持久性的情况下进行该查询。例如:

seFirestore().enablePersistence()
.then(() => {
  let documentReference = firestore
    .collection("food")
    .doc("milkshake");
  const { data } = useFirestoreDocData(documentReference);
})
.catch(error => {
  console.error("enablePersistence failed", error);
})

请注意仅在完全启用持久性后查询将如何完成。

感谢@DougStevenson 和@Ajordat 的建议

在应用程序组件中:


import { useFirestore } from "reactfire"

...

const firestore = useFirestore();

React.useEffect(() => {
  firestore.enablePersistence();
}, []);



在您要使用 Firestore 的自定义组件中:


import { useFirestore, useFirestoreDocData /* or what you want to use */ } from "reactfire"


let docRef = useFirestore()
  .collection("food")
  .doc("milkshake");

let { data: document } = useFirestoreDocData(docRef);

console.log(document);