[英]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.