Repository navigation
Conversation
…4137) getData applied its result as a server overwrite at the query's location, even for a query with a limit or range, whose result is only part of the data there. Other listeners at or below the location, and the disk cache, lost the data that wasn't in the result. For example, after a get for the three children before "f", a listener for the children from "f" on at the same location had no children. Now, like the JS SDK's get(), a filtered result is applied only to a view for the query, which the sync tree adds without a listen for the duration of the update. The disk cache merges the result instead of replacing the data at the location. Results of queries that load all data are still applied as a server overwrite.
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request fixes an issue where calling getData on a query with a limit or range could incorrectly remove data from other listeners at or below the query's location, as well as from the disk cache. It introduces applyGetResultForQuery:newData: in FSyncTree to apply the query result specifically to the query's own view without setting up a persistent listen or triggering unnecessary listener changes. This is achieved by adding helper methods to skip listener setup and deduplication during registration and removal. Comprehensive integration and unit tests have been added to verify this behavior. There are no review comments, so I have no feedback to provide.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request addresses an issue where calling getData on a query with a limit or range could incorrectly remove data from other listeners at or below the query's location, as well as from the disk cache. To resolve this, the changes introduce applyGetResultForQuery:newData: in FSyncTree to apply the query result specifically to its own view without triggering a full server overwrite, utilizing temporary event registrations that skip listener setup and deduplication. Comprehensive integration and unit tests have been added to verify this behavior. There are no review comments, so I have no additional feedback to provide.
Fixes #14137
Fixes #8286
Problem
getDataapplied its result withapplyServerOverwriteAtPath:at the query's location, even for a query with a limit or range. That result is only part of the data at the location, so the overwrite replaced:queryStartingAtValue:listener lost all its children after aqueryEndingBeforeValue:+queryLimitedToLast:get. In Possible bug in “queryOrdered(byChild:).queryEqual(toValue:).getData" function #8286, a listener without a filter fired again with only the child that aqueryEqualToValue:get returned.Fix
FRepo getData:now calls a new-[FSyncTree applyGetResultForQuery:newData:]. For a query that loads all data, it still applies a server overwrite. For any other query, it applies the result the way the JS SDK'srepoGetValuedoes:The registration is a new
FKeepSyncedEventRegistrationinstance. It raises no events and only matches itself, so an existing listener orkeepSyncedregistration on the same query stays in place and gets the result.addEventRegistration:andremoveEventRegistration:get private variants withskipListenerSetupandskipListenerDedupflags, like the JS SDK'sskipSetupListenerandskipListenerDedup.This is separate from #12168, which #16721 fixes. Thanks to @diegogarciar and @fawzialrifai for the reports.
Testing
7 new unit tests in
FSyncPointTests.mforapplyGetResultForQuery:newData:. These 4 fail without the fix:The other 3 check that a get starts and stops no listens and leaves no tag, keeps a
keepSyncedquery synced, and raises events for a listener on the same query.4 new integration tests in
FIRDatabaseQueryTests.mfor the same 4 cases. All 4 fail without the fix.DatabaseUnit(SPM, macOS): 436 tests pass.FIRDatabaseQueryTests,FKeepSyncedTestandFPersistintegration tests, against the RTDB emulator: 139/139 pass.Merged with fix(database): resend in-flight gets after reconnect #16719, fix(database): avoid crash on get error without reason #16720 and fix(database): return child data from getData under observed parent #16721, only
CHANGELOG.mdconflicts. The first commit of this PR also passed the unit and integration tests in that merge (447 and 140 tests).