【发布时间】:2021-05-01 17:53:03
【问题描述】:
我在 Angular 11+ 上使用 AngularFire 作为 Firebase 的 API。
我的应用的域名是实时拍卖
理想情况下,我想做的是阅读所有文档,然后订阅每个文档以进行更改。
我目前的烦恼是我在 Firestore 上的读取次数。
我的集合读取将产生 N 次读取。但是订阅每个文档会产生额外的读取,默认情况下会产生 2N 次读取,这似乎是不可避免的。
但我想这比在集合上留下订阅并在每次更新集合中的某些内容时接收 N 次读取要好。
因此,使用下面的示例代码,我对集合进行查询,然后对文档进行另一个查询。为重现而简化。
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。
上面的示例代码将使内部 observable 仅按预期发出 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 上的读取量也很高。
【问题讨论】:
-
Firestore 肯定有优化空间。通常,您(几乎)永远不想阅读集合的所有文档。回答我这个问题: 1:你为什么要阅读所有文件? 2:为什么要听变化?可能有更好的方法来实现您的目标。
-
我没有阅读所有文件,只是为了简单起见。我实际上有虚拟滚动和分页。我希望阅读文件,因为我需要知道我在拍卖中拥有哪些物品并进行渲染。我需要听取更改,因为它是一个实时拍卖应用程序,并且我正在更新出价,并且当用户在页面上时,文档会随着用户活动随时间而变化如果我不是在听单个项目,而是只订阅每次更新该页面中的任何项目时,我都会检索 PAGE_SIZE 文档。这也不是最佳的。
-
我的拍卖详情页面包含一些拍卖详情和拍卖物品的无限滚动页面及其当前出价。我的模型是:拍卖集合,其中每个拍卖文件都有项目集合。当用户出价时,我只是更新项目的当前出价值。如果用户当前正在观察该项目,这应该反映到 UI
标签: angular google-cloud-firestore angularfire