Skip to content

Commit 484e90a

Browse files
Compat class for DocumentReference (#4043)
1 parent 6be9225 commit 484e90a

File tree

13 files changed

+266
-424
lines changed

13 files changed

+266
-424
lines changed

.changeset/short-mangos-beg.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@firebase/firestore": patch
3+
---
4+
5+
Internal changes to support upcoming modular API.

packages/firestore/exp/src/api/reference.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import { FirebaseFirestore } from './database';
1919
import {
20-
_DocumentKeyReference,
2120
ParsedUpdateData,
2221
parseSetData,
2322
parseUpdateData,
@@ -80,6 +79,7 @@ import {
8079
removeSnapshotsInSyncListener
8180
} from '../../../src/core/event_manager';
8281
import { FirestoreError } from '../../../src/util/error';
82+
import { Compat } from '../../../src/compat/compat';
8383

8484
/**
8585
* An options object that can be passed to {@link onSnapshot()} and {@link
@@ -374,6 +374,12 @@ export function updateDoc(
374374

375375
const dataReader = newUserDataReader(firestore);
376376

377+
// For Compat types, we have to "extract" the underlying types before
378+
// performing validation.
379+
if (fieldOrUpdateData instanceof Compat) {
380+
fieldOrUpdateData = fieldOrUpdateData._delegate;
381+
}
382+
377383
let parsed: ParsedUpdateData;
378384
if (
379385
typeof fieldOrUpdateData === 'string' ||
@@ -821,7 +827,7 @@ export function executeWrite(
821827
*/
822828
function convertToDocSnapshot<T>(
823829
firestore: FirebaseFirestore,
824-
ref: _DocumentKeyReference<T>,
830+
ref: DocumentReference<T>,
825831
snapshot: ViewSnapshot
826832
): DocumentSnapshot<T> {
827833
debugAssert(

packages/firestore/exp/src/api/snapshot.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,7 @@ export class DocumentSnapshot<T = DocumentData> extends LiteDocumentSnapshot<
238238
this._firestoreImpl._databaseId,
239239
options?.serverTimestamps || DEFAULT_SERVER_TIMESTAMP_BEHAVIOR,
240240
key =>
241-
new DocumentReference(
242-
this._firestore,
243-
/* converter= */ null,
244-
key.path
245-
),
241+
new DocumentReference(this._firestore, /* converter= */ null, key),
246242
bytes => new Bytes(bytes)
247243
);
248244
return userDataWriter.convertValue(this._document.toProto()) as T;
@@ -276,8 +272,7 @@ export class DocumentSnapshot<T = DocumentData> extends LiteDocumentSnapshot<
276272
const userDataWriter = new UserDataWriter(
277273
this._firestoreImpl._databaseId,
278274
options.serverTimestamps || DEFAULT_SERVER_TIMESTAMP_BEHAVIOR,
279-
key =>
280-
new DocumentReference(this._firestore, this._converter, key.path),
275+
key => new DocumentReference(this._firestore, this._converter, key),
281276
bytes => new Bytes(bytes)
282277
);
283278
return userDataWriter.convertValue(value);

packages/firestore/exp/test/shim.ts

+6-191
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,16 @@ import * as exp from '../index';
2020

2121
import {
2222
addDoc,
23-
collection,
24-
deleteDoc,
2523
doc,
26-
DocumentReference as DocumentReferenceExp,
2724
FieldPath as FieldPathExp,
28-
getDoc,
29-
getDocFromCache,
30-
getDocFromServer,
3125
getDocs,
3226
getDocsFromCache,
3327
getDocsFromServer,
3428
onSnapshot,
3529
query,
3630
queryEqual,
3731
refEqual,
38-
setDoc,
3932
snapshotEqual,
40-
updateDoc,
4133
endAt,
4234
endBefore,
4335
startAfter,
@@ -49,13 +41,17 @@ import {
4941
Bytes as BytesExp
5042
} from '../../exp/index';
5143
import { UntypedFirestoreDataConverter } from '../../src/api/user_data_reader';
52-
import { isPartialObserver, PartialObserver } from '../../src/api/observer';
5344
import {
5445
isPlainObject,
5546
validateSetOptions
5647
} from '../../src/util/input_validation';
5748
import { Compat } from '../../src/compat/compat';
58-
import { Firestore } from '../../src/api/database';
49+
import {
50+
Firestore,
51+
DocumentReference,
52+
wrapObserver,
53+
extractSnapshotOptions
54+
} from '../../src/api/database';
5955

6056
export { GeoPoint, Timestamp } from '../index';
6157

@@ -188,129 +184,6 @@ export class WriteBatch
188184
}
189185
}
190186

191-
export class DocumentReference<T = legacy.DocumentData>
192-
extends Compat<exp.DocumentReference<T>>
193-
implements legacy.DocumentReference<T> {
194-
constructor(
195-
readonly firestore: Firestore,
196-
delegate: exp.DocumentReference<T>
197-
) {
198-
super(delegate);
199-
}
200-
201-
readonly id = this._delegate.id;
202-
readonly path = this._delegate.path;
203-
204-
get parent(): legacy.CollectionReference<T> {
205-
return new CollectionReference<T>(this.firestore, this._delegate.parent);
206-
}
207-
208-
collection(
209-
collectionPath: string
210-
): legacy.CollectionReference<legacy.DocumentData> {
211-
return new CollectionReference(
212-
this.firestore,
213-
collection(this._delegate, collectionPath)
214-
);
215-
}
216-
217-
isEqual(other: DocumentReference<T>): boolean {
218-
return refEqual(this._delegate, other._delegate);
219-
}
220-
221-
set(data: Partial<T>, options?: legacy.SetOptions): Promise<void> {
222-
if (options) {
223-
validateSetOptions('DocumentReference.set', options);
224-
return setDoc(this._delegate, unwrap(data), options);
225-
} else {
226-
return setDoc(this._delegate, unwrap(data));
227-
}
228-
}
229-
230-
update(data: legacy.UpdateData): Promise<void>;
231-
update(
232-
field: string | FieldPath,
233-
value: any,
234-
...moreFieldsAndValues: any[]
235-
): Promise<void>;
236-
update(
237-
dataOrField: any,
238-
value?: any,
239-
...moreFieldsAndValues: any[]
240-
): Promise<void> {
241-
if (arguments.length === 1) {
242-
return updateDoc(this._delegate, unwrap(dataOrField));
243-
} else {
244-
return updateDoc(
245-
this._delegate,
246-
unwrap(dataOrField),
247-
unwrap(value),
248-
...unwrap(moreFieldsAndValues)
249-
);
250-
}
251-
}
252-
253-
delete(): Promise<void> {
254-
return deleteDoc(this._delegate);
255-
}
256-
257-
get(options?: legacy.GetOptions): Promise<DocumentSnapshot<T>> {
258-
let snap: Promise<exp.DocumentSnapshot<T>>;
259-
if (options?.source === 'cache') {
260-
snap = getDocFromCache(this._delegate);
261-
} else if (options?.source === 'server') {
262-
snap = getDocFromServer(this._delegate);
263-
} else {
264-
snap = getDoc(this._delegate);
265-
}
266-
return snap.then(result => new DocumentSnapshot(this.firestore, result));
267-
}
268-
269-
onSnapshot(observer: {
270-
next?: (snapshot: DocumentSnapshot<T>) => void;
271-
error?: (error: legacy.FirestoreError) => void;
272-
complete?: () => void;
273-
}): () => void;
274-
onSnapshot(
275-
options: legacy.SnapshotListenOptions,
276-
observer: {
277-
next?: (snapshot: DocumentSnapshot<T>) => void;
278-
error?: (error: legacy.FirestoreError) => void;
279-
complete?: () => void;
280-
}
281-
): () => void;
282-
onSnapshot(
283-
onNext: (snapshot: DocumentSnapshot<T>) => void,
284-
onError?: (error: legacy.FirestoreError) => void,
285-
onCompletion?: () => void
286-
): () => void;
287-
onSnapshot(
288-
options: legacy.SnapshotListenOptions,
289-
onNext: (snapshot: DocumentSnapshot<T>) => void,
290-
onError?: (error: legacy.FirestoreError) => void,
291-
onCompletion?: () => void
292-
): () => void;
293-
onSnapshot(...args: any): () => void {
294-
const options = extractSnapshotOptions(args);
295-
const observer = wrapObserver<DocumentSnapshot<T>, exp.DocumentSnapshot<T>>(
296-
args,
297-
snap => new DocumentSnapshot(this.firestore, snap)
298-
);
299-
return onSnapshot(this._delegate, options, observer);
300-
}
301-
302-
withConverter<U>(
303-
converter: legacy.FirestoreDataConverter<U>
304-
): DocumentReference<U> {
305-
return new DocumentReference<U>(
306-
this.firestore,
307-
this._delegate.withConverter(
308-
converter as UntypedFirestoreDataConverter<U>
309-
)
310-
);
311-
}
312-
}
313-
314187
export class DocumentSnapshot<T = legacy.DocumentData>
315188
extends Compat<exp.DocumentSnapshot<T>>
316189
implements legacy.DocumentSnapshot<T> {
@@ -634,8 +507,6 @@ function wrap(firestore: Firestore, value: any): any {
634507
return new FieldPath(...value._internalPath.toArray());
635508
} else if (value instanceof BytesExp) {
636509
return new Blob(value);
637-
} else if (value instanceof DocumentReferenceExp) {
638-
return new DocumentReference(firestore, value);
639510
} else if (isPlainObject(value)) {
640511
const obj: any = {};
641512
for (const key in value) {
@@ -672,59 +543,3 @@ function unwrap(value: any): any {
672543
return value;
673544
}
674545
}
675-
676-
/**
677-
* Creates an observer that can be passed to the firestore-exp SDK. The
678-
* observer converts all observed values into the format expected by the shim.
679-
*
680-
* @param args The list of arguments from an `onSnapshot` call.
681-
* @param wrapper The function that converts the firestore-exp type into the
682-
* type used by this shim.
683-
*/
684-
function wrapObserver<ShimType, ExpType>(
685-
args: any,
686-
wrapper: (val: ExpType) => ShimType
687-
): PartialObserver<ExpType> {
688-
let userObserver: PartialObserver<ShimType>;
689-
if (isPartialObserver(args[0])) {
690-
userObserver = args[0] as PartialObserver<ShimType>;
691-
} else if (isPartialObserver(args[1])) {
692-
userObserver = args[1];
693-
} else if (typeof args[0] === 'function') {
694-
userObserver = {
695-
next: args[0],
696-
error: args[1],
697-
complete: args[2]
698-
};
699-
} else {
700-
userObserver = {
701-
next: args[1],
702-
error: args[2],
703-
complete: args[3]
704-
};
705-
}
706-
707-
return {
708-
next: val => {
709-
if (userObserver!.next) {
710-
userObserver!.next(wrapper(val));
711-
}
712-
},
713-
error: userObserver.error?.bind(userObserver),
714-
complete: userObserver.complete?.bind(userObserver)
715-
};
716-
}
717-
718-
/**
719-
* Iterates the list of arguments from an `onSnapshot` call and returns the
720-
* first argument that may be an `SnapshotListenOptions` object. Returns an
721-
* empty object if none is found.
722-
*/
723-
function extractSnapshotOptions(args: any): exp.SnapshotListenOptions {
724-
for (const arg of args) {
725-
if (typeof arg === 'object' && !isPartialObserver(arg)) {
726-
return arg as exp.SnapshotListenOptions;
727-
}
728-
}
729-
return {};
730-
}

0 commit comments

Comments
 (0)