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?
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.