[英]Why does my Firestore listener with offline persistence always read from the server?
I am using Firebase JavaScript Modular Web Version 9 SDK with my Vue 3 / TypeScript app.
我的理解是,当使用具有离线持久性的 Firestore 实时侦听器时,它应该像这样工作:
但是我已经设置了离线持久性,为我的 Firestore 数据创建了一个监听器,并监控了读取的来源......
在我的应用程序中,我看到了从本地缓存中的初始读取(预期),然后是从服务器立即读取的第二次(意外)。 之后所有后续读取都来自服务器(也是意外的)。
在此测试期间,我的数据都没有改变。 所以我希望回调监听器的所有读取都来自本地缓存,而不是服务器。
实际上,我唯一一次从本地缓存中看到读取是在侦听器第一次启动时,但这是意料之中的。
可能是什么问题呢?
PS 为了进行这些“后续调用”,我将导航到我的 SPA 的另一个页面,然后返回到我的组件所在的页面以再次触发它。
src/composables/database.ts
export const useLoadWebsite = () => {
const q = query(
collection(db, 'websites'),
where('userId', '==', 'NoLTI3rDlrZtzWCbsZpPVtPgzOE3')
);
const firestoreWebsite = ref<DocumentData>();
onSnapshot(q, { includeMetadataChanges: true }, (querySnapshot) => {
const source = querySnapshot.metadata.fromCache ? 'local cache' : 'server';
console.log('Data came from ' + source);
const colArray: DocumentData[] = [];
querySnapshot.docs.forEach((doc) => {
colArray.push({ ...doc.data(), id: doc.id });
});
firestoreWebsite.value = colArray[0];
});
return firestoreWebsite;
};
src/components/websiteUrl.vue
<template>
<div v-if="website?.url">{{ website.url }}</div>
</template>
<script setup lang="ts">
import { useLoadWebsite } from '../composables/database';
const website = useLoadWebsite();
</script>
没有什么是错的。 你所描述的完全按照我的预期工作。
Firestore 本地持久性并不意味着完全替代后端。 默认情况下,它是在后端不可用的情况下作为临时数据源。 如果后端可用,则 SDK 将更愿意确保客户端应用程序与其完全同步,并在后端可用时提供所有更新。
如果您想强制查询仅使用缓存而不使用后端,您可以以编程方式将缓存指定为该查询的源。
如果您出于某种原因根本不想从服务器进行任何更新,那么您可以完全禁用网络访问。
也可以看看:
我弄清楚为什么我得到的结果与预期的不同。
罪魁祸首是{ includeMetadataChanges: true }
。
如docs 中所述,该选项将触发元数据更改的侦听器事件。
因此,侦听器回调也在每次元数据更改时触发,而不仅仅是数据读取和写入,导致我看到奇怪的结果。
删除它后,它开始按预期工作,我通过检查 Firebase 控制台中的使用图来验证它,该图显示了读取和快照侦听器的数量。
这是删除该选项的完整代码:
export const useLoadWebsite = () => {
const q = query(
collection(db, 'websites'),
where('userId', '==', 'NoLTI3rDlrZtzWCbsZpPVtPgzOE3')
);
const firestoreWebsite = ref<DocumentData>();
onSnapshot(q, (querySnapshot) => {
const source = querySnapshot.metadata.fromCache ? 'local cache' : 'server';
console.log('Data came from ' + source);
const colArray: DocumentData[] = [];
querySnapshot.docs.forEach((doc) => {
colArray.push({ ...doc.data(), id: doc.id });
});
firestoreWebsite.value = colArray[0];
});
return firestoreWebsite;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.