Skip to content

Commit c4f71b1

Browse files
Ensure consistent JSON Serialization of DocumentKeys
1 parent 9bb3603 commit c4f71b1

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

packages/firestore/src/core/sync_engine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
204204

205205
const queryView = this.queryViewsByQuery.get(query);
206206
if (queryView) {
207-
// PORTING NOTE: With Mult-Tab Web, it is possible that a query view
207+
// PORTING NOTE: With Multi-Tab Web, it is possible that a query view
208208
// already exists when EventManager calls us for the first time. This
209209
// happens when the primary tab is already listening to this query on
210210
// behalf of another tab and the user of the primary also starts listening

packages/firestore/src/model/path.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ export abstract class Path {
7373
return this.len;
7474
}
7575

76+
toJSON(): string[] {
77+
return this.segments.slice(this.offset, this.limit());
78+
}
79+
7680
isEqual(other: Path): boolean {
7781
return Path.comparator(this, other) === 0;
7882
}

packages/firestore/test/integration/api/query.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ import {
3232
withTestDb
3333
} from '../util/helpers';
3434

35-
const Timestamp = firebase.firestore!.Timestamp;
35+
const Blob = firebase.firestore!.Blob;
3636
const FieldPath = firebase.firestore!.FieldPath;
37+
const GeoPoint = firebase.firestore!.GeoPoint;
38+
const Timestamp = firebase.firestore!.Timestamp;
3739

3840
// TODO(b/116617988): Use public API.
3941
interface FirestoreInternal extends firestore.FirebaseFirestore {
@@ -694,4 +696,35 @@ apiDescribe('Queries', persistence => {
694696
expect(querySnapshot.docs.map(d => d.id)).to.deep.equal(['cg-doc2']);
695697
});
696698
});
699+
700+
it('can query custom types', () => {
701+
return withTestCollection(persistence, {}, async ref => {
702+
const data = {
703+
ref: ref.firestore.doc('f/c'),
704+
geoPoint: new GeoPoint(0, 0),
705+
buffer: Blob.fromBase64String('Zm9v'),
706+
time: Timestamp.now()
707+
};
708+
await ref.add({ data });
709+
710+
// In https://github.com/firebase/firebase-js-sdk/issues/1524, a
711+
// customer was not able to unlisten from a query that contained a
712+
// nested object with a DocumentReference. The cause of it was that our
713+
// serialization of nested references via JSON.stringify() was different
714+
// for Queries created via the API layer versus Queries read from
715+
// persistence. To simulate this issue, we have to listen and unlisten
716+
// to the same query twice.
717+
const query = ref.where('data', '==', data);
718+
719+
for (let i = 0; i < 2; ++i) {
720+
const deferred = new Deferred();
721+
const unsubscribe = query.onSnapshot(snapshot => {
722+
expect(snapshot.size).to.equal(1);
723+
deferred.resolve();
724+
});
725+
await deferred.promise;
726+
unsubscribe();
727+
}
728+
});
729+
});
697730
});

packages/firestore/test/unit/model/path.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ describe('Path', () => {
171171
expect(abc.isPrefixOf(ba)).to.equal(false);
172172
});
173173

174+
it('respects offset during JSON serialization', () => {
175+
const path1 = new ResourcePath(['c']);
176+
const path2 = new ResourcePath(['a', 'b', 'c'], 2);
177+
expect(JSON.stringify(path1)).to.equal(JSON.stringify(path2));
178+
});
179+
174180
it('can be constructed from field path.', () => {
175181
const path = FieldPath.fromServerFormat('foo\\..bar\\\\.baz');
176182
expect(path.toArray()).to.deep.equal(['foo.', 'bar\\', 'baz']);

packages/firestore/test/util/helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,8 @@ export function expectNotEqual(left: any, right: any, message?: string): void {
565565
}
566566

567567
export function expectEqualArrays(
568-
left: unknown[],
569-
right: unknown[],
568+
left: Array<unknown>,
569+
right: Array<unknown>,
570570
message?: string
571571
): void {
572572
message = message ? ' ' + message : '';

0 commit comments

Comments
 (0)