Fix stream cache semantics for PUT vs PATCH and include TobyFix package/namespace rename#332
Open
canedha wants to merge 2 commits intostep-up-labs:masterfrom
Open
Fix stream cache semantics for PUT vs PATCH and include TobyFix package/namespace rename#332canedha wants to merge 2 commits intostep-up-labs:masterfrom
canedha wants to merge 2 commits intostep-up-labs:masterfrom
Conversation
Collaborator
|
Your changes touched 48 files, most of them unrelated, with a namespace update. Please revert those changes before I can review the rest |
Author
|
Hi Tomas,
the actual functional fix is small and isolated. The namespace/package
rename is intentionally kept and can be ignored for review.
Problem summary:
The streaming cache treated Firebase REST stream `put` and `patch` events
with effectively the same merge behavior.
That is wrong semantically:
- `put` should replace the data at the target path
- `patch` should merge into the existing data at the target path
Because of this, stale properties could remain in cached objects after a
`put` event if the new payload no longer contained fields that existed
before.
Files with the actual functional fix:
- `src/Firebase/Streaming/FirebaseSubscription.cs`
- `src/Firebase/Streaming/FirebaseCache.cs`
What changed:
1) `FirebaseSubscription.ProcessServerData(...)`
Before, both `put` and `patch` ended up calling the cache without
preserving the actual server event type.
Old:
`this.cache.PushData(this.elementRoot + path, data);`
New:
`this.cache.PushData(this.elementRoot + path, data, serverEvent);`
2) `FirebaseCache.PushData(...)`
A new overload was added that accepts `FirebaseServerEventType`.
Behavior now:
- `Put` => replace semantics
- `Patch` => merge semantics
Specifically:
- for dictionary targets, `Put` clears/replaces contents, `Patch` merges
keys
- for object/property targets, `Put` replaces the target value/object,
`Patch` keeps using merge-style population
The main bug was that object updates previously used merge-style population
for both event types, which is correct for `patch` but incorrect for `put`.
If you only want to review the functional fix, please look only at:
- `src/Firebase/Streaming/FirebaseSubscription.cs`
- `src/Firebase/Streaming/FirebaseCache.cs`
Everything else is package/namespace identity separation for my downstream
fork.
Best regards,
Tobias
Am Mi., 18. März 2026 um 09:59 Uhr schrieb Tomas Bezouska <
***@***.***>:
… *bezysoftware* left a comment (step-up-labs/firebase-database-dotnet#332)
<#332 (comment)>
Your changes touched 48 files, most of them unrelated, with a namespace
update. Please revert those changes before I can review the rest
—
Reply to this email directly, view it on GitHub
<#332 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/APX6P35T5KLDSVMFXPWEUQT4RJQONAVCNFSM6AAAAACWVMYJEOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DAOBQHAZDSOBRG4>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes an issue in the streaming cache logic where
putandpatchevents were effectively handled with the same merge behavior.For Firebase Realtime Database REST streaming, these two event types have different semantics:
putshould replace the data at the target path, whilepatchshould merge into the existing data at the target path. Before this change, the cache update path used merge-style behavior for both event types, which could leave stale properties behind when an object was replaced by aputevent and the new payload no longer contained fields that had existed before.Root cause
The streaming code already receives distinct Firebase server event types (
putvspatch), but that distinction was not preserved when data was pushed into the cache.In
FirebaseSubscription.ProcessServerData(...), bothPutandPatcheventually went through the same cache call. InsideFirebaseCache.PushData(...), object updates ended up using merge-style population logic. That behavior is correct forpatch, but incorrect forput.Because of that, if a cached object previously contained a property that was no longer present in a later full replacement payload, the cache could merge the new payload into the existing object and leave the old property behind instead of removing it.
Changes
Preserve the actual Firebase server event type when pushing into the cache.
File:
src/Firebase/Streaming/FirebaseSubscription.csChange:
ProcessServerData(...)now passes the receivedFirebaseServerEventTypeinto the cache layer, instead of treatingputandpatchthe same at that boundary.Split cache behavior by event semantics.
File:
src/Firebase/Streaming/FirebaseCache.csChanges:
PushData(...)that acceptsFirebaseServerEventTypePutandPatchNew semantics:
Putreplaces dictionary contents instead of merging themPutreplaces object/property values at the target path instead of merge-populating themPatchkeeps existing merge behaviorPatchonly applies the incoming keys/properties to the existing cached objectThis restores the correct realtime cache semantics and prevents stale properties from surviving a full object replacement.
Package / assembly / namespace rename to TobyFix.
Files:
src/Firebase/Firebase.csprojsrc/Firebase/...Changes:
FirebaseDatabase.net-TobyFixFirebaseDatabase.net.TobyFixFirebase.TobyFix...This rename is included because the downstream consumer uses the patched package under a clearly separated identity and should not mix it with the original package.
Why this matters
Without this fix, the stream cache can diverge from the actual Firebase state after a
putevent. A full object replacement can behave like a partial merge, which means removed properties may incorrectly remain in cached objects. After this fix,putreplaces the target state andpatchcontinues to merge incremental changes.Files touched
Functional fix:
src/Firebase/Streaming/FirebaseSubscription.cssrc/Firebase/Streaming/FirebaseCache.csPackage / identity rename:
src/Firebase/Firebase.csprojsrc/Firebase/...Validation performed
Validated against a real downstream client setup using Firebase Realtime Database streaming.
Test scenario:
Observed result:
putandpatchNotes
This PR includes both:
If preferred, these can be split into separate PRs, but they are kept together here because the downstream implementation and validation were performed against the renamed package.