-
Notifications
You must be signed in to change notification settings - Fork 946
Fix array-contains queries #1913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -25,6 +25,9 @@ import { GeoPoint } from '../../../../src/api/geo_point'; | |||
import { Timestamp } from '../../../../src/api/timestamp'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't figure out how to test KeyFieldFilter
due to problems with creating a query with this filter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is what you mean, but it might look something like:
const input = filter(DOCUMENT_KEY_NAME, '==', ref('project/database', 'coll/doc'));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! That worked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good with a bit of suggested improvement to make the FieldFilter
constructor protected to prevent this mistake going forward. But we could do that later, in a separate PR if you prefer.
@@ -1282,7 +1282,7 @@ export class JsonProtoSerializer { | |||
} | |||
|
|||
fromFieldFilter(filter: api.Filter): Filter { | |||
return new FieldFilter( | |||
return Filter.create( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two other instances of new FieldFilter()
in this file that I think should optimally be FieldFilter.create()
as well (though in practice they're not harmful).
To make sure we don't mess this up going forward, I think it might make sense to move Filter.create()
to be FieldFilter.create()
so we can make the FieldFilter
constructor protected
. This is probably more correct anyway, since the only kind of filter that Filter.create() could conceivably create with its current arguments is FieldFilter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, and I like this suggestion. Done, PTAL.
expect(s.fromFieldFilter(actual)).to.deep.equal(input); | ||
const roundtripped = s.fromFieldFilter(actual); | ||
expect(roundtripped).to.deep.equal(input); | ||
expect(roundtripped).to.be.instanceof(FieldFilter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW we could instead do:
expect(Object.getPrototypeOf(roundtripped)).to.equal(Object.getPrototypeOf(input));
to avoid the redundancy of specifying the type of input
... but in practice it doesn't matter and it's easier to read as-is... so probably not a good improvement (unless we wanted to refactor these tests to share code or something).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how getPrototypeOf
works -- if it checks for the exact class, then it could be an improvement, because given, say, ArrayContainsFilter
, it will nevertheless satisfy a check for instanceof FieldFilter
(due to inheritance).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes. I believe the prototype check would be more strict than that... that said it's not super normal to deal with an object's prototype directly or do equal checks on it. I am not 100% confident it wouldn't bite us in the future some day (due to browser differences or something). So I don't feel strongly that it's a better approach or anything (i.e. feel free to leave as-is).
commits.txt
Outdated
fd5a31a6bba01b79f9fd269c96926c8aa6248701 Generate a new token after getId calls if there is no valid token (#1869) | ||
99e6cc8267d4eea4b2893a45d097c6cb20eddd15 Add support for running Firestore integration tests against the emulator (#1851) | ||
3f2c7bf8a08978bea065ac1706af016e8646f234 Check that window is complete in BrowserConnectivityMonitor (#1870) | ||
73f10767a8473468aa6fb6300abe93f998b59ecf Minor style changes for a RTDB comment block (#1857) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
Think you accidentally added some extra files...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's the prettier script striking again. Removed now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks!
expect(roundtripped).to.be.instanceof(FieldFilter); | ||
}); | ||
|
||
it('converts key field', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding!
* Rename relation_filter.{h,cc} to field_filter.{h,cc} * Rename RelationFilter to FieldFilter * Move Filter::Create to FieldFilter * Port api::Query::ValidateNewFilter * Add ArrayContainsFilter * Add KeyFieldFilter * Make FieldFilter constructor protected * Port FieldFilter refactor from the JS SDK firebase/firebase-js-sdk#1894 * Add spec test from firebase/firebase-js-sdk#1913 * Accept array-contains as a synonym for array_contains
#1894 introduced a regression that made persisted queries deserialize incorrectly. Fix the regression and add tests.
The root cause is that the refactoring introduced a type hierarchy of classes derived from
FieldFilter
, but serializer always deserializes persisted filters to the base classFieldFilter
, never to the derived types. This would have affected array-contains queries, in queries, and key field queries.Fixes #1904.