Angular + Firebase firestore - 内部订阅文档 returns 初始订阅时有两个值

Angular + Firebase firestore - inner subscription to document returns two values on initial subscribe

我在 Angular 11+ 上使用 AngularFire 作为我的 API for firebase。

我的应用程序的域是 real-time 拍卖

理想情况下,我想做的是阅读所有文档,然后订阅每个文档以进行更改。

我目前的问题是我在 firestore 上的读取次数。

我的 collection 读取将产生 N 个读取。但是订阅每个文档都会产生额外的读取,默认情况下会产生 2N 次读取,这似乎是不可避免的。

但我想这比在 collection 上留下订阅并在每次更新 collection 的内容时接收 N 次阅读要好。

因此,使用下面的示例代码,我对 collection 进行了查询,然后对文档进行了另一个查询。简化只是为了复制。

  this.store.collection("users").valueChanges()
  .pipe(
    take(1),
    concatMap(() => this.store.doc("user/1").valueChanges())
  )
  .subscribe(console.log(user));

但是,Inner observable 会发射 2 次。

一次使用 added,一次使用 modified 快照更改类型。

所以我的问题是:

为什么我的内部 observable 在初始订阅时连续发射两次,而在我看来它应该只发射一次。

如果这两个发射都算作 firestore 上的读取,这将产生 3N 次读取。

通过我在 firestore 监控页面上的测试,情况似乎是这样,因为在 400 个文档页面上,我在 firestore 上记录了大约 1200 次读取并计入了定价。

  1. 我在示例代码中可能做错了什么?

  2. 有没有人建议我应该如何检索更多数据 读取次数少,效率高?

  3. 我应该切换到 RTDB 吗,它似乎有更慷慨的报价 10GB 数据输出对我的读取量来说哪个更好?

编辑:

所以我刚刚用 angularfire API 测试了 firebase RTDB。

像上面这样的示例代码将使内部可观察对象仅按预期发出 1 个值,并且每个项目更改 1 个。这是预期的。

我仍然不清楚为什么 firestore 实施会发出 2 个值,这两个值既算作已读又会影响定价。

结束代码看起来像这样:

this.db.list<AuctionItem>(`auctions/1/items`)
.valueChanges()
.pipe(
  take(1),
  tap(items => this.itemsToRender = items),
  mergeMap(items => [...items]),
  mergeMap((item: AuctionItem) => this.db.object(`auctions/1/items/${item.id}`).valueChanges() as Observable<AuctionItem>),
)
.subscribe(change => {
  // do work when item updates
})

仍然不确定为什么 firestore 不能按预期为我工作。考虑使用部分 firestore + RTDB 以实现最佳使用,因为即使有 50k 免费,我在 firestore 上的读取量也很高。

在你的情况下我会这样做:

  1. 做一个onSnapshot()查询,(第一个读操作) --> 但将结果限制为 10 或 20。(便宜!)
  2. 在用户滚动时 -> 加载更多。 (Firestore pagination ref)
  3. 文档更改时-->更新显示的数据

监听更改时,您只需为确实更改了的文档再次付费,而不是您已查询但未获得任何更新的文档。

有关听众定价的更多详细信息,请观看 this video (especially at 3:16)