英文:
Can't read data from cache in Angular Firestore with persistence enabled after reload
问题
我有一个使用Angular 15 (15.2.0)和Angular Fire 7.5.0 (Firebase 9)的项目,结构如下:
AppModule
| LoginModule(延迟加载)与守卫:canActivate(() => redirectLoggedInTo(['']))
| HomeModule(延迟加载)与守卫:canActivate(() => redirectUnauthorizedTo(['/login']))
我在AppModule
中使用以下代码提供Firestore并启用持久性:
provideFirestore(() => {
console.log('从AppModule提供');
const firestore = initializeFirestore(getApp(), {
ignoreUndefinedProperties: true,
cacheSizeBytes: CACHE_SIZE_UNLIMITED
});
enableIndexedDbPersistence(firestore).then(() => console.log('提供完成')).catch((err) => {
if (err.code == 'failed-precondition') {
console.error('多个标签页打开,只能在一个标签页中启用持久性。')
} else if (err.code == 'unimplemented') {
console.error('当前浏览器不支持启用持久性所需的所有功能。');
}
});
return firestore;
}),
当应用程序首次加载时,provideFirestore
中的两个控制台消息都会打印出来。我登录后,在HomeModule
中可以读取数据。第一次,缓存中没有任何内容,所以它会从服务器中读取数据。随后的调用会成功从缓存中获取数据。
这是我如何读取数据的方式:
const q = query(
collection(getFirestore(), 'myCollection'),
where('_userId', '==', getAuth().currentUser?.uid),
orderBy('id', 'asc')
);
// 我使用这个从缓存中读取数据
getDocsFromCache(q);
// 如果查询快照为空,我从服务器中读取
getDocsFromServer(q);
问题出现在我重新加载页面时。AppModule
中的“提供”控制台消息不会打印出来。每次调用都会从服务器中获取数据,getDocsFromCache
永远不会返回文档。
我检查了IndexedDB,首次加载应用程序时的数据仍然存在,但无法读取,新数据也不会存储。
如果我手动注销然后重新登录,我会再次从缓存中获取数据,因此我认为问题与Angular有关,但我无法找出问题所在。问题可能出在哪里?
英文:
I have a project with Angular 15 (15.2.0) and Angular Fire 7.5.0 (Firebase 9), that looks like this:
AppModule
| LoginModule (lazy-loaded) with guard: canActivate(() => redirectLoggedInTo(['']))
| HomeModule (lazy-loaded) with guard: canActivate(() => redirectUnauthorizedTo(['/login']))
I'm using this code in the AppModule
to provide Firestore and enable persistence:
provideFirestore(() => {
console.log('providing from AppModule');
const firestore = initializeFirestore(getApp(), {
ignoreUndefinedProperties: true,
cacheSizeBytes: CACHE_SIZE_UNLIMITED
});
enableIndexedDbPersistence(firestore).then(() => console.log('provided')).catch((err) => {
if (err.code == 'failed-precondition') {
console.error('Multiple tabs open, persistence can only be enabled in one tab at a a time.')
} else if (err.code == 'unimplemented') {
console.error('The current browser does not support all of the features required to enable persistence');
}
});
return firestore;
}),
When the app is loaded the first time, both console messages in provideFirestore
are printed. I login and then in HomeModule
I can read data. First time, there's nothing in cache, so it reads from the server. Subsequent calls fetch data successfully from cache.
This is how I'm reading data:
const q = query(
collection(getFirestore(), 'myCollection'),
where('_userId', '==', getAuth().currentUser?.uid),
orderBy('id', 'asc')
);
// I use this to read from cache
getDocsFromCache(q);
// If the querySnapshot is empty, I read from server
getDocsFromServer(q);
The problem is when I reload the page. The "providing" console messages from AppModule
won't print. Every call will fetch data from the server, getDocsFromCache
will never return documents.
I inspected the IndexedDB and the data from when I first loaded the app is still there, but it can't be read, and new data won't be stored.
If I manually logout and log back in, I get data from cache again, so I think the issue is related to Angular, but I can't figure it out. Where could be the problem?
答案1
得分: -1
The solution is to move enableIndexedDbPersistence
to the AppModule
constructor:
export class AppModule {
constructor(firestore: Firestore) {
enableIndexedDbPersistence(firestore).catch((err) => {
if (err.code == 'failed-precondition') {
console.error('Multiple tabs open, persistence can only be enabled in one tab at a a time.')
} else if (err code == 'unimplemented') {
console.error('The current browser does not support all of the features required to enable persistence');
}
});
}
}
Can't know for sure why the original code is not working, though it was in another project with Angular 13. Maybe some libraries were loaded at different times.
英文:
The solution is to move enableIndexedDbPersistence
to the AppModule
constructor:
export class AppModule {
constructor(firestore: Firestore) {
enableIndexedDbPersistence(firestore).catch((err) => {
if (err.code == 'failed-precondition') {
console.error('Multiple tabs open, persistence can only be enabled in one tab at a a time.')
} else if (err.code == 'unimplemented') {
console.error('The current browser does not support all of the features required to enable persistence');
}
});
}
}
Can't know for sure why the original code is not working, though it was in another project with Angular 13. Maybe some libraries were loaded at different times.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论