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 次读取并计入了定价。
我在示例代码中可能做错了什么?
有没有人建议我应该如何检索更多数据
读取次数少,效率高?
我应该切换到 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 上的读取量也很高。
在你的情况下我会这样做:
- 做一个onSnapshot()查询,(第一个读操作)
--> 但将结果限制为 10 或 20。(便宜!)
- 在用户滚动时 -> 加载更多。 (Firestore pagination ref)
- 文档更改时-->更新显示的数据
监听更改时,您只需为确实更改了的文档再次付费,而不是您已查询但未获得任何更新的文档。
有关听众定价的更多详细信息,请观看 this video (especially at 3:16)
我在 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 次读取并计入了定价。
我在示例代码中可能做错了什么?
有没有人建议我应该如何检索更多数据 读取次数少,效率高?
我应该切换到 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 上的读取量也很高。
在你的情况下我会这样做:
- 做一个onSnapshot()查询,(第一个读操作) --> 但将结果限制为 10 或 20。(便宜!)
- 在用户滚动时 -> 加载更多。 (Firestore pagination ref)
- 文档更改时-->更新显示的数据
监听更改时,您只需为确实更改了的文档再次付费,而不是您已查询但未获得任何更新的文档。
有关听众定价的更多详细信息,请观看 this video (especially at 3:16)