无法在启用持久性的情况下重新加载后从 Angular Firestore 缓存中读取数据。

huangapple go评论64阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年3月7日 11:30:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657808.html