Proposal (Firestore): better default behaviour for the `collectionData` and `docData` functions (for the underlying SDK's handling of optimistic updates)
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 35/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 技术栈
- firebase, typescript
- 领域
- databases
调研方向
根据 issue 中描述的实现链,跟踪 collectionData 和 docData 调用经过 collection、doc 和 fromRef 直到 SDK 的 onSnapshot 监听器。验证 includeMetadataChanges 的默认行为以及由此产生的 optimistic/server update 发出;当所提议的默认值和 collection/doc 的直接配置按指定方式工作时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
tl;dr
Make a technically breaking change to the collectionData and docData functions to always have includeMetadataChanges set to false when listening for snapshots.
Background
The underlying Firebase SDK for Firestore performs optimistic updates on the client, with a hasPendingWrites metadata flag available on snapshots to tell you when a server-side update has been committed (only if you've called the underlying onSnapshot with includeMetadataChanges: true, which is what rxfire currently does). From the docs:
Local writes in your app will invoke snapshot listeners immediately. This is because of an important feature called "latency compensation." When you perform a write, your listeners will be notified with the new data before the data is sent to the backend.
Retrieved documents have a
metadata.hasPendingWritesproperty that indicates whether the document has local changes that haven't been written to the backend yet.Source: https://firebase.google.com/docs/firestore/query-data/listen#events-local-changes
This behaviour results in a very common "why am I seeing two updates trigger for my snapshot?" (though only when includeMetadataChanges is set to true). The idea is that you could filter out and choose which of the updates to respond to in your implementation (or something more elaborate, e.g. to handle offline scenarios).
Note: it's not clear (at least, to me) what happens if a server-side error occurs (e.g. security rules fail) but I'll assume for now that a failure always results in a new snapshot being emitted.
Problem: double updates emitted when using the rxfire collectionData and docData functions with no way to filter out
In the current rxfire implementation, the collectionData and docData functions end up setting includeMetadataChanges: true when setting up the snapshot listener. So if an update is made to any document in the collection (or to the single document) being observed then two whole emissions of the collection (or document) are made in the observable – one for the client-side optimistic update and another once the server-side update has committed. This has been reported previously in: https://github.com/FirebaseExtended/rxfire/issues/50.
This would normally be okay except the emitted value of both functions do not have the hasPendingWrites metadata flag, so it's impossible to choose when to filter out one of the emitted results. And since there's no way to explicitly set includeMetadataChanges to false when listening to the snapshot we have to live with this behaviour (with some folks resorting to workarounds).
Note: the same behviour is true of the collection and data functions, but in those cases we do have access to the hasPendingWrites flag so we have control over which we filter out.
Proposed solution
An attempt was made to allow configuring the includeMetadataChanges option in https://github.com/FirebaseExtended/rxfire/pull/12.
Instead of the approach taken there, this proposal suggests:
- Changing the default behaviour of the
collectionDataanddocDatarxfire functions to always haveincludeMetadataChangesset tofalsewhen setting up the snapshot listener.- This is technically a breaking change but may not have a big impact as the net effect is that the same results will be emitted once, rather than twice. So it's only a "breaking" change if folks were relying on this double update behaviour (as opposed to treating it like a bug).
- Rationale: these methods are essentially convenience methods on top of the underlying SDK, which simplify usage (e.g. setting the ID field). So it could make sense to also abstract away the metadata change and use the default behaviour of the underlying SDK.
- And as a result of this implementation change (see below), allowing the
collectionanddocrxfire functions to be passed in a value forincludeMetadataChanges, defaulting totrue(as it is now).
Implementation details
The current implementation chain goes like (shown for collection, but the same for doc):
sequenceDiagram
collectionData (rxfire)-->>collection (rxfire): ...
collection (rxfire)-->>fromRef (rxfire): includeMetadataChanges: true
fromRef (rxfire)-->>onSnapshot (SDK): ...
Proposed solution:
sequenceDiagram
collectionData (rxfire)-->>collection (rxfire): includeMetadataChanges: false
collection (rxfire)-->>fromRef (rxfire): includeMetadataChanges: false<br/>but could be true if collection called directly
fromRef (rxfire)-->>onSnapshot (SDK): ...
/cc @davideast
- 主要语言
- TypeScript
- 星标
- 150
- 派生
- 50
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
FirebaseExtended/rxfire 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 30/100
FirebaseExtended/rxfire#105 ·
-
难度 3/5 1-2 天 新手友好度 35/100
FirebaseExtended/rxfire#94 ·
-
难度 1/5 1 小时以内 新手友好度 35/100
FirebaseExtended/rxfire#90 ·
-
难度 3/5 1-2 天 新手友好度 35/100
FirebaseExtended/rxfire#88 · 10 条评论 · 14 个 reaction ·
-
collectionChanges is firing for every element on a single deletion可能已有人在做 @davideast 于 1171 天前认领。 未关闭
FirebaseExtended/rxfire#75 · 3 条评论 · 已指派 1 人 ·
查看 FirebaseExtended/rxfire 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
apache/rocketmq-dashboard#6872 ·
维护者通常 3 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 70/100
fab-geocommuns/RNB-site#539 ·
维护者通常 2 天内回复
-
Guest multiview tile label leaks raw virtual-source-id "Whip" instead of the guest name / slot label未关闭
难度 2/5 1-3 小时 新手友好度 62/100
Eyevinn/open-live-studio#211 ·
维护者通常 1 天内回复
-
documentation good first issue
难度 2/5 半天 新手友好度 72/100
sujithputta02/Esapay#13 ·
-
难度 2/5 1-3 小时 新手友好度 65/100
ehmpathy/rhachet-roles-bhuild#468 ·
维护者通常 1 天内回复