From df8e63468d2f589b67bab66f6c5087a8e433c4e6 Mon Sep 17 00:00:00 2001 From: tylim Date: Mon, 18 Jul 2022 20:28:20 +0800 Subject: [PATCH 1/3] refactoring and housekeeping --- package.json | 2 +- src/batch/index.ts | 2 +- src/onSnapshot/onSnapshot.ts | 6 +-- src/operations/updateDoc.ts | 2 +- src/refs/collection.ts | 2 +- src/refs/collectionGroup.ts | 2 +- src/refs/doc.ts | 2 +- src/rulesUnitTesting.test.ts | 9 ++-- src/transaction/index.ts | 2 +- src/types/WriteBatch.ts | 52 ++++++++++++++++++ src/types/alias.ts | 15 ++++++ src/types/delete.ts | 4 +- src/types/index.ts | 3 ++ src/types/ori.ts | 2 +- src/types/ref.ts | 101 +---------------------------------- src/types/set.ts | 4 +- src/types/snapshot.ts | 15 ++---- src/types/transaction.ts | 47 ++++++++++++++++ src/types/update.ts | 3 +- 19 files changed, 145 insertions(+), 130 deletions(-) create mode 100644 src/types/WriteBatch.ts create mode 100644 src/types/alias.ts create mode 100644 src/types/transaction.ts diff --git a/package.json b/package.json index e494bb7..ac68473 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firelordjs", - "version": "1.4.8", + "version": "1.4.9", "description": "🔥 Extremely High Precision Typescript Wrapper for Firestore Web, Providing Unparalleled Type Safe and Dev Experience", "source": "src/index.ts", "main": "dist/src/index.js", diff --git a/src/batch/index.ts b/src/batch/index.ts index 9e6ac29..c45f43f 100644 --- a/src/batch/index.ts +++ b/src/batch/index.ts @@ -17,7 +17,7 @@ export const writeBatch = ( ): WriteBatch => { const batch = writeBatch_( // @ts-expect-error - firestore || getFirestore() // ! type messed up, after adding firestore of testing type, weird + firestore || getFirestore() ) return Object.freeze({ commit: () => batch.commit(), diff --git a/src/onSnapshot/onSnapshot.ts b/src/onSnapshot/onSnapshot.ts index 2d65c20..39751be 100644 --- a/src/onSnapshot/onSnapshot.ts +++ b/src/onSnapshot/onSnapshot.ts @@ -30,7 +30,7 @@ export const onSnapshot: OnSnapshot = ( options?: OriSnapshotListenOptions ) => { const newOnError = isOptions(onError) ? undefined : onError - const newOncCompletion = isOptions(onCompletion) ? undefined : onCompletion + const newOnCompletion = isOptions(onCompletion) ? undefined : onCompletion const newOptions = options || (isOptions(onError) ? onError : undefined) || @@ -41,14 +41,14 @@ export const onSnapshot: OnSnapshot = ( // @ts-expect-error next: onNext, error: newOnError, - complete: newOncCompletion, + complete: newOnCompletion, }) : onSnapshot_( reference as OriQuery, // @ts-expect-error onNext, newOnError, - newOncCompletion + newOnCompletion ) } diff --git a/src/operations/updateDoc.ts b/src/operations/updateDoc.ts index 234a1c8..8b5b2bb 100644 --- a/src/operations/updateDoc.ts +++ b/src/operations/updateDoc.ts @@ -19,6 +19,6 @@ export const updateDoc = (( ) => { const ref = // @ts-expect-error - updateDoc_(reference, flatten(data)) // ! type messed up, after adding firestore of testing type, weird + updateDoc_(reference, flatten(data)) // ! testing messed up the type, weird return ref }) as unknown as Update diff --git a/src/refs/collection.ts b/src/refs/collection.ts index 75d1ef8..226910f 100644 --- a/src/refs/collection.ts +++ b/src/refs/collection.ts @@ -13,7 +13,7 @@ export const collectionCreator = (firestore?: FirestoreAndFirestoreTesting) => { return collection_( // @ts-expect-error - firestore || fStore, // ! type messed up, after adding firestore of testing type, weird + firestore || fStore, // ! testing messed up the type, weird collectionPath ) as CollectionReference } diff --git a/src/refs/collectionGroup.ts b/src/refs/collectionGroup.ts index ea9f852..38badc1 100644 --- a/src/refs/collectionGroup.ts +++ b/src/refs/collectionGroup.ts @@ -9,7 +9,7 @@ export const collectionGroupCreator = (firestore?: FirestoreAndFirestoreTesting) => { return collectionGroup_( // @ts-expect-error - firestore || fStore, // ! type messed up, after adding firestore of testing type, weird + firestore || fStore, // ! testing messed up the type, weird collectionID ) as Query } diff --git a/src/refs/doc.ts b/src/refs/doc.ts index 7383e17..bae4a8c 100644 --- a/src/refs/doc.ts +++ b/src/refs/doc.ts @@ -18,7 +18,7 @@ export const docCreator = const docId = isFirestore(firestore) ? documentId : firestore return doc_( // @ts-expect-error - fs, // ! type messed up, after adding firestore of testing type, weird + fs, // ! testing messed up the type, weird collectionPath + '/' + docId ) as DocumentReference } diff --git a/src/rulesUnitTesting.test.ts b/src/rulesUnitTesting.test.ts index 1beb946..67632f5 100644 --- a/src/rulesUnitTesting.test.ts +++ b/src/rulesUnitTesting.test.ts @@ -71,7 +71,7 @@ describe('test whether works with rules-unit-testing', () => { }) it('test addDoc and deleteDoc', async () => { const data = generateRandomData() - const ref = userRef.collection(firestore) + const ref = userRef.collection() const docRef = await addDoc(ref, data) await readThenCompareWithWriteData(data, docRef) await deleteDoc(docRef) @@ -87,7 +87,7 @@ describe('test whether works with rules-unit-testing', () => { expect.hasAssertions() const querySnapshot = await getDocs( query( - userRef.collectionGroup(firestore), + userRef.collectionGroup(), where('a.b.c', '==', data.a.b.c as number) ) ) @@ -108,10 +108,7 @@ describe('test whether works with rules-unit-testing', () => { expect.hasAssertions() setDoc(docRef, data).then(() => { const unsub = onSnapshot( - query( - userRef.collection(firestore), - where('a.b.c', '==', data.a.b.c as number) - ), + query(userRef.collection(), where('a.b.c', '==', data.a.b.c as number)), async querySnapshot => { const queryDocumentSnapshot = querySnapshot.docs.filter( doc => doc.id === docId diff --git a/src/transaction/index.ts b/src/transaction/index.ts index e016628..3d15e40 100644 --- a/src/transaction/index.ts +++ b/src/transaction/index.ts @@ -15,7 +15,7 @@ export const runTransaction: RunTransaction = (firestore, updateFunction) => { const callback = isFirestore(firestore) ? updateFunction : firestore return runTransaction_( // @ts-expect-error - fStore, // ! type messed up, after adding firestore of testing type, weird + fStore, // ! testing messed up the type, weird async transaction => { const set = setCreator(transaction) diff --git a/src/types/WriteBatch.ts b/src/types/WriteBatch.ts new file mode 100644 index 0000000..922be1b --- /dev/null +++ b/src/types/WriteBatch.ts @@ -0,0 +1,52 @@ +import { WriteBatchSet } from './set' +import { WriteBatchUpdate } from './update' +import { WriteBatchDelete } from './delete' + +export interface WriteBatch { + /** + * Writes to the document referred to by the provided {@link + * DocumentReference}. If the document does not exist yet, it will be created. + * If you provide `merge` or `mergeFields`, the provided data can be merged + * into an existing document. + * + * @param documentRef - A reference to the document to be set. + * @param data - An object of the fields and values for the document. + * @param options - An object to configure the set behavior. + * @throws Error - If the provided input is not a valid Firestore document. + * @returns This `WriteBatch` instance. Used for chaining method calls. + */ + set: WriteBatchSet + /** + * Updates fields in the document referred to by the provided {@link + * DocumentReference}. The update will fail if applied to a document that does + * not exist. + * + * @param documentRef - A reference to the document to be updated. + * @param data - An object containing the fields and values with which to + * update the document. Fields can contain dots to reference nested fields + * within the document. + * @throws Error - If the provided input is not valid Firestore data. + * @returns This `WriteBatch` instance. Used for chaining method calls. + */ + update: WriteBatchUpdate + /** + * Deletes the document referred to by the provided {@link DocumentReference}. + * + * @param documentRef - A reference to the document to be deleted. + * @returns This `WriteBatch` instance. Used for chaining method calls. + */ + delete: WriteBatchDelete + /** + * Commits all of the writes in this write batch as a single atomic unit. + * + * The result of these writes will only be reflected in document reads that + * occur after the returned promise resolves. If the client is offline, the + * write fails. If you would like to see local modifications or buffer writes + * until the client is online, use the full Firestore SDK. + * + * @returns A `Promise` resolved once all of the writes in the batch have been + * successfully written to the backend as an atomic unit (note that it won't + * resolve while you're offline). + */ + commit(): Promise +} diff --git a/src/types/alias.ts b/src/types/alias.ts new file mode 100644 index 0000000..a49bdb5 --- /dev/null +++ b/src/types/alias.ts @@ -0,0 +1,15 @@ +import { + OriFirestore, + OriSnapshotMetadata, + OriSnapshotOptions, + OriSnapshotListenOptions, + OriDocumentChangeType, + OriFirestoreTesting, +} from './ori' +export type Firestore = OriFirestore +export type FirestoreTesting = OriFirestoreTesting +export type FirestoreAndFirestoreTesting = Firestore | FirestoreTesting +export type SnapshotMetadata = OriSnapshotMetadata +export type SnapshotOptions = OriSnapshotOptions +export type SnapshotListenOptions = OriSnapshotListenOptions +export type DocumentChangeType = OriDocumentChangeType diff --git a/src/types/delete.ts b/src/types/delete.ts index 5293fdc..dc7efa8 100644 --- a/src/types/delete.ts +++ b/src/types/delete.ts @@ -1,5 +1,7 @@ import { MetaType } from './metaTypeCreator' -import { DocumentReference, Transaction, WriteBatch } from './ref' +import { DocumentReference } from './ref' +import { Transaction } from './transaction' +import { WriteBatch } from './WriteBatch' type DeleteCreator = ( reference: DocumentReference diff --git a/src/types/index.ts b/src/types/index.ts index 6d29a7b..3a5fb12 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -16,3 +16,6 @@ export * from './cursor' export * from './queryConstraintLimitation' export * from './fieldPath' export * from './validID' +export * from './alias' +export * from './WriteBatch' +export * from './transaction' diff --git a/src/types/ori.ts b/src/types/ori.ts index 09749ec..f2e8c08 100644 --- a/src/types/ori.ts +++ b/src/types/ori.ts @@ -1,6 +1,6 @@ import { RulesTestContext } from '@firebase/rules-unit-testing' -export type OriFirestore = ReturnType +export type OriFirestore = ReturnType // ! OriFirebaseFirestore['Firestore'] doesn't work even though they are the exact same type??? export type OriFirestoreTesting = ReturnType diff --git a/src/types/ref.ts b/src/types/ref.ts index 05c9015..c07a43d 100644 --- a/src/types/ref.ts +++ b/src/types/ref.ts @@ -1,13 +1,6 @@ import { MetaType } from './metaTypeCreator' -import { OriFirestore, OriFirestoreTesting } from './ori' -import { Get } from './get' -import { TransactionSet, WriteBatchSet } from './set' -import { TransactionUpdate, WriteBatchUpdate } from './update' -import { TransactionDelete, WriteBatchDelete } from './delete' +import { Firestore } from './alias' -export type Firestore = OriFirestore -export type FirestoreTesting = OriFirestoreTesting -export type FirestoreAndFirestoreTesting = Firestore | FirestoreTesting export interface DocumentReference { /** The type of this Firestore reference. */ readonly type: 'document' @@ -59,95 +52,3 @@ export interface Query { */ readonly firestore: Firestore } - -export interface Transaction { - /** - * Reads the document referenced by the provided {@link DocumentReference}. - * - * @param documentRef - A reference to the document to be read. - * @returns A `DocumentSnapshot` with the read data. - */ - get: Get - /** - * Writes to the document referred to by the provided {@link - * DocumentReference}. If the document does not exist yet, it will be created. - * If you provide `merge` or `mergeFields`, the provided data can be merged - * into an existing document. - * - * @param documentRef - A reference to the document to be set. - * @param data - An object of the fields and values for the document. - * @param options - An object to configure the set behavior. - * @throws Error - If the provided input is not a valid Firestore document. - * @returns This `Transaction` instance. Used for chaining method calls. - */ - set: TransactionSet - /** - * Updates fields in the document referred to by the provided {@link - * DocumentReference}. The update will fail if applied to a document that does - * not exist. - * - * @param documentRef - A reference to the document to be updated. - * @param data - An object containing the fields and values with which to - update the document. Fields can contain dots to reference nested fields - within the document. - * @throws Error - If the provided input is not valid Firestore data. - * @returns This `Transaction` instance. Used for chaining method calls. - */ - update: TransactionUpdate - /** - * Deletes the document referred to by the provided {@link DocumentReference}. - * - * @param documentRef - A reference to the document to be deleted. - * @returns This `Transaction` instance. Used for chaining method calls. - */ - delete: TransactionDelete -} - -export interface WriteBatch { - /** - * Writes to the document referred to by the provided {@link - * DocumentReference}. If the document does not exist yet, it will be created. - * If you provide `merge` or `mergeFields`, the provided data can be merged - * into an existing document. - * - * @param documentRef - A reference to the document to be set. - * @param data - An object of the fields and values for the document. - * @param options - An object to configure the set behavior. - * @throws Error - If the provided input is not a valid Firestore document. - * @returns This `WriteBatch` instance. Used for chaining method calls. - */ - set: WriteBatchSet - /** - * Updates fields in the document referred to by the provided {@link - * DocumentReference}. The update will fail if applied to a document that does - * not exist. - * - * @param documentRef - A reference to the document to be updated. - * @param data - An object containing the fields and values with which to - * update the document. Fields can contain dots to reference nested fields - * within the document. - * @throws Error - If the provided input is not valid Firestore data. - * @returns This `WriteBatch` instance. Used for chaining method calls. - */ - update: WriteBatchUpdate - /** - * Deletes the document referred to by the provided {@link DocumentReference}. - * - * @param documentRef - A reference to the document to be deleted. - * @returns This `WriteBatch` instance. Used for chaining method calls. - */ - delete: WriteBatchDelete - /** - * Commits all of the writes in this write batch as a single atomic unit. - * - * The result of these writes will only be reflected in document reads that - * occur after the returned promise resolves. If the client is offline, the - * write fails. If you would like to see local modifications or buffer writes - * until the client is online, use the full Firestore SDK. - * - * @returns A `Promise` resolved once all of the writes in the batch have been - * successfully written to the backend as an atomic unit (note that it won't - * resolve while you're offline). - */ - commit(): Promise -} diff --git a/src/types/set.ts b/src/types/set.ts index 3ccb76e..4cd912a 100644 --- a/src/types/set.ts +++ b/src/types/set.ts @@ -1,10 +1,12 @@ import { MetaType } from './metaTypeCreator' -import { DocumentReference, Transaction, WriteBatch } from './ref' +import { DocumentReference } from './ref' import { PartialNoUndefinedAndNoUnknownMemberNoEmptyMember, RecursivelyReplaceDeleteFieldWithErrorMsg, } from './partialNoUndefinedAndNoUnknownMember' import { DeepKeyHybrid } from './objectFlatten' +import { Transaction } from './transaction' +import { WriteBatch } from './WriteBatch' type SetCreator = < T extends MetaType, diff --git a/src/types/snapshot.ts b/src/types/snapshot.ts index 21692d7..c01fe64 100644 --- a/src/types/snapshot.ts +++ b/src/types/snapshot.ts @@ -1,21 +1,16 @@ import { MetaType } from './metaTypeCreator' import { - OriSnapshotMetadata, - OriSnapshotOptions, - OriSnapshotListenOptions, - OriDocumentChangeType, -} from './ori' + SnapshotMetadata, + SnapshotOptions, + SnapshotListenOptions, + DocumentChangeType, +} from './alias' import { UnionReadServerTimestampWithNullFlatten, UnionReadServerTimestampWithNull, } from './unionReadTimestampWithNull' import { DocumentReference, Query } from './ref' -export type SnapshotMetadata = OriSnapshotMetadata -export type SnapshotOptions = OriSnapshotOptions -export type SnapshotListenOptions = OriSnapshotListenOptions -export type DocumentChangeType = OriDocumentChangeType - export interface DocumentSnapshot { /** * Metadata about the `DocumentSnapshot`, including information about its diff --git a/src/types/transaction.ts b/src/types/transaction.ts new file mode 100644 index 0000000..d548351 --- /dev/null +++ b/src/types/transaction.ts @@ -0,0 +1,47 @@ +import { Get } from './get' +import { TransactionSet } from './set' +import { TransactionUpdate } from './update' +import { TransactionDelete } from './delete' + +export interface Transaction { + /** + * Reads the document referenced by the provided {@link DocumentReference}. + * + * @param documentRef - A reference to the document to be read. + * @returns A `DocumentSnapshot` with the read data. + */ + get: Get + /** + * Writes to the document referred to by the provided {@link + * DocumentReference}. If the document does not exist yet, it will be created. + * If you provide `merge` or `mergeFields`, the provided data can be merged + * into an existing document. + * + * @param documentRef - A reference to the document to be set. + * @param data - An object of the fields and values for the document. + * @param options - An object to configure the set behavior. + * @throws Error - If the provided input is not a valid Firestore document. + * @returns This `Transaction` instance. Used for chaining method calls. + */ + set: TransactionSet + /** + * Updates fields in the document referred to by the provided {@link + * DocumentReference}. The update will fail if applied to a document that does + * not exist. + * + * @param documentRef - A reference to the document to be updated. + * @param data - An object containing the fields and values with which to + update the document. Fields can contain dots to reference nested fields + within the document. + * @throws Error - If the provided input is not valid Firestore data. + * @returns This `Transaction` instance. Used for chaining method calls. + */ + update: TransactionUpdate + /** + * Deletes the document referred to by the provided {@link DocumentReference}. + * + * @param documentRef - A reference to the document to be deleted. + * @returns This `Transaction` instance. Used for chaining method calls. + */ + delete: TransactionDelete +} diff --git a/src/types/update.ts b/src/types/update.ts index 3756cfc..fa49045 100644 --- a/src/types/update.ts +++ b/src/types/update.ts @@ -3,7 +3,8 @@ import { DocumentReference, PartialNoUndefinedAndNoUnknownMemberNoEmptyMember, } from '../types' -import { Transaction, WriteBatch } from './ref' +import { Transaction } from './transaction' +import { WriteBatch } from './WriteBatch' export type UpdateCreator = < T extends MetaType, From 06de400b0d09bdf80c433bca2754c4706cb6da06 Mon Sep 17 00:00:00 2001 From: tylim Date: Tue, 19 Jul 2022 05:37:25 +0800 Subject: [PATCH 2/3] 1. tons of cleanup 2. rename setting `allFieldsPossiblyUndefined` as `allFieldsPossiblyReadAsUndefined` --- CHANGELOG.md | 4 +++ codeForDoc/src/possiblyUndefined.ts | 2 +- package.json | 2 +- src/batch/delete.ts | 9 +++-- src/batch/set.ts | 8 ++--- src/batch/update.ts | 6 ++-- src/equal/refEqual.ts | 9 +++-- src/equal/snapshotEqual.ts | 10 +++--- src/onSnapshot/onSnapshot.test.ts | 4 +-- src/onSnapshot/onSnapshot.ts | 20 ++++++----- src/operations/addDoc.ts | 2 +- src/operations/deleteDoc.ts | 12 +++++-- src/operations/getDoc.ts | 32 ++++++----------- src/operations/getDocs.ts | 21 +++++------- src/operations/setDoc.ts | 10 ++---- src/operations/updateDoc.ts | 11 +++--- src/queryClauses/where.ts | 7 +--- src/transaction/delete.ts | 11 +++--- src/transaction/get.ts | 13 +++---- src/transaction/set.ts | 17 +++++---- src/transaction/update.ts | 14 ++++---- src/types/alias.ts | 4 +++ src/types/metaTypeCreator.test.ts | 2 +- src/types/metaTypeCreator.ts | 53 ++++++++++++++++++----------- src/types/ori.ts | 20 ----------- 25 files changed, 138 insertions(+), 165 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6281f8e..c8d69b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # HISTORY +## v1.5.0 19-July-2022 + +- rename setting `allFieldsPossiblyUndefined` as `allFieldsPossiblyReadAsUndefined` + ## v1.3.0 6-May-2022 - orderBy('\_name') cursor now only accept full doc path, if input type is string, require const assertion or else display "Please use const assertion" error message. diff --git a/codeForDoc/src/possiblyUndefined.ts b/codeForDoc/src/possiblyUndefined.ts index ca02951..e9c2711 100644 --- a/codeForDoc/src/possiblyUndefined.ts +++ b/codeForDoc/src/possiblyUndefined.ts @@ -38,7 +38,7 @@ type abc2 = MetaTypeCreator< 'abc', string, null, // no parent - { allFieldsPossiblyUndefined: true } + { allFieldsPossiblyReadAsUndefined: true } > const docRef2 = getFirelord()('abc').doc('efg') diff --git a/package.json b/package.json index ac68473..9010bc0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firelordjs", - "version": "1.4.9", + "version": "1.5.0", "description": "🔥 Extremely High Precision Typescript Wrapper for Firestore Web, Providing Unparalleled Type Safe and Dev Experience", "source": "src/index.ts", "main": "dist/src/index.js", diff --git a/src/batch/delete.ts b/src/batch/delete.ts index c091f4c..c70c217 100644 --- a/src/batch/delete.ts +++ b/src/batch/delete.ts @@ -1,7 +1,6 @@ import { OriWriteBatch, OriDocumentReference, WriteBatchDelete } from '../types' -export const deleteCreator = ((writeBatch: OriWriteBatch) => - (reference: OriDocumentReference) => { - const ref = writeBatch.delete(reference) - return ref - }) as unknown as (writeBatch: OriWriteBatch) => WriteBatchDelete +export const deleteCreator = (writeBatch: OriWriteBatch) => + ((reference: OriDocumentReference) => { + return writeBatch.delete(reference) + }) as WriteBatchDelete diff --git a/src/batch/set.ts b/src/batch/set.ts index 0934322..251f439 100644 --- a/src/batch/set.ts +++ b/src/batch/set.ts @@ -6,8 +6,8 @@ import { WriteBatchSet, } from '../types' -export const setCreator = ((writeBatch: OriWriteBatch) => - ( +export const setCreator = (writeBatch: OriWriteBatch) => + (( reference: OriDocumentReference, data: OriDocumentData, options?: OriSetOptions @@ -16,6 +16,4 @@ export const setCreator = ((writeBatch: OriWriteBatch) => ? writeBatch.set(reference, data, options) : writeBatch.set(reference, data) return ref - }) as unknown as setCreator - -type setCreator = (writeBatch: OriWriteBatch) => WriteBatchSet + }) as WriteBatchSet diff --git a/src/batch/update.ts b/src/batch/update.ts index 6d9c0d7..54e74dc 100644 --- a/src/batch/update.ts +++ b/src/batch/update.ts @@ -1,12 +1,12 @@ import { OriWriteBatch, OriDocumentReference, WriteBatchUpdate } from '../types' import { flatten } from '../utils' -export const updateCreator = ((writeBatch: OriWriteBatch) => - (reference: OriDocumentReference, data: Record) => { +export const updateCreator = (writeBatch: OriWriteBatch) => + ((reference: OriDocumentReference, data: Record) => { const ref = writeBatch.update( reference, // @ts-expect-error flatten(data) ) return ref - }) as unknown as (writeBatch: OriWriteBatch) => WriteBatchUpdate + }) as WriteBatchUpdate diff --git a/src/equal/refEqual.ts b/src/equal/refEqual.ts index 77d8c69..88a17a2 100644 --- a/src/equal/refEqual.ts +++ b/src/equal/refEqual.ts @@ -9,9 +9,12 @@ import { DocumentReference, CollectionReference, MetaType } from '../types' * @returns true if the references point to the same location in the same * Firestore database. */ -export const refEqual = ( - left: DocumentReference | CollectionReference, - right: DocumentReference | CollectionReference +export const refEqual = < + T extends DocumentReference | CollectionReference, + U extends T +>( + left: T, + right: U ) => { return refEqual_( // @ts-expect-error diff --git a/src/equal/snapshotEqual.ts b/src/equal/snapshotEqual.ts index ed3519b..67aea1e 100644 --- a/src/equal/snapshotEqual.ts +++ b/src/equal/snapshotEqual.ts @@ -8,12 +8,14 @@ import { DocumentSnapshot, QuerySnapshot, MetaType } from '../types' * @param right - A snapshot to compare. * @returns true if the snapshots are equal. */ -export const snapshotEqual = ( +export const snapshotEqual = < // ! DocumentSnapshot does not extends DocumentSnapshot...why? same case with QuerySnapshot // eslint-disable-next-line @typescript-eslint/no-explicit-any - left: DocumentSnapshot | QuerySnapshot, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - right: DocumentSnapshot | QuerySnapshot + T extends DocumentSnapshot | QuerySnapshot, + U extends T +>( + left: T, + right: U ) => { return snapshotEqual_( // @ts-expect-error diff --git a/src/onSnapshot/onSnapshot.test.ts b/src/onSnapshot/onSnapshot.test.ts index 6cd2988..4c2aa1b 100644 --- a/src/onSnapshot/onSnapshot.test.ts +++ b/src/onSnapshot/onSnapshot.test.ts @@ -44,7 +44,7 @@ describe('test onSnapshot', () => { ) }) }) - it('test one doc functionality and type with options', done => { + it('test one doc functionality and type', done => { const docRef = userRef.doc('onSnapshotWithOptionsOneDocTest') const data = generateRandomData() expect.hasAssertions() @@ -68,7 +68,7 @@ describe('test onSnapshot', () => { ) }) }) - it('test naked query functionality and type', done => { + it('test naked query functionality and type with options', done => { const docId = 'onSnapshotNakedQueryTest' const docRef = userRef.doc(docId) const data = generateRandomData() diff --git a/src/onSnapshot/onSnapshot.ts b/src/onSnapshot/onSnapshot.ts index 39751be..d09e517 100644 --- a/src/onSnapshot/onSnapshot.ts +++ b/src/onSnapshot/onSnapshot.ts @@ -6,9 +6,11 @@ import { OriFirestoreError, OriSnapshotListenOptions, OriQuery, - OriUnsubscribe, + Unsubscribe, DocumentSnapshot, QuerySnapshot, + FirestoreError, + SnapshotListenOptions, } from '../types' export const isOptions = ( @@ -79,10 +81,10 @@ type OnSnapshot = { ? DocumentSnapshot : QuerySnapshot ) => void, - onError?: (error: OriFirestoreError) => void, + onError?: (error: FirestoreError) => void, onCompletion?: () => void, - options?: OriSnapshotListenOptions - ): OriUnsubscribe + options?: SnapshotListenOptions + ): Unsubscribe /** * Attaches a listener for `DocumentSnapshot` events. You may either pass * individual `onNext` and `onError` callbacks or pass a single observer @@ -107,9 +109,9 @@ type OnSnapshot = { ? DocumentSnapshot : QuerySnapshot ) => void, - onError?: (error: OriFirestoreError) => void, - options?: OriSnapshotListenOptions - ): OriUnsubscribe + onError?: (error: FirestoreError) => void, + options?: SnapshotListenOptions + ): Unsubscribe /** * Attaches a listener for `DocumentSnapshot` events. You may either pass * individual `onNext` and `onError` callbacks or pass a single observer @@ -132,6 +134,6 @@ type OnSnapshot = { ? DocumentSnapshot : QuerySnapshot ) => void, - options?: OriSnapshotListenOptions - ): OriUnsubscribe + options?: SnapshotListenOptions + ): Unsubscribe } diff --git a/src/operations/addDoc.ts b/src/operations/addDoc.ts index fce0a89..67f28e6 100644 --- a/src/operations/addDoc.ts +++ b/src/operations/addDoc.ts @@ -19,5 +19,5 @@ export const addDoc = ( // @ts-expect-error reference, data - ) as unknown as Promise> + ) as Promise> } diff --git a/src/operations/deleteDoc.ts b/src/operations/deleteDoc.ts index 66715f4..269996f 100644 --- a/src/operations/deleteDoc.ts +++ b/src/operations/deleteDoc.ts @@ -1,7 +1,13 @@ import { deleteDoc as deleteDoc_ } from 'firebase/firestore' import { OriDocumentReference, Delete } from '../types' +/** +Deletes the document referred to by the specified DocumentReference. + +@param reference — A reference to the document to delete. + +@returns A Promise resolved once the document has been successfully deleted from the backend (note that it won't resolve while you're offline). +*/ export const deleteDoc = ((reference: OriDocumentReference) => { - const ref = deleteDoc_(reference) - return ref -}) as unknown as Delete + return deleteDoc_(reference) +}) as Delete diff --git a/src/operations/getDoc.ts b/src/operations/getDoc.ts index 837ff8f..46d1eb2 100644 --- a/src/operations/getDoc.ts +++ b/src/operations/getDoc.ts @@ -3,7 +3,7 @@ import { getDocFromCache as getDocFromCache_, getDocFromServer as getDocFromServer_, } from 'firebase/firestore' -import { Get } from '../types' +import { Get, OriDocumentReference, DocumentSnapshot, MetaType } from '../types' /** Reads the document referred to by this DocumentReference. @@ -14,13 +14,9 @@ Note: getDoc() attempts to provide up-to-date data when possible by waiting for @returns A Promise resolved with a DocumentSnapshot containing the current document contents. */ -// @ts-expect-error -export const getDoc: Get = reference => { - return getDoc_( - // @ts-expect-error - reference - ) -} +export const getDoc: Get = ((reference: OriDocumentReference) => { + return getDoc_(reference) as Promise> +}) as Get /** * Reads the document referred to by this `DocumentReference` from cache. @@ -29,13 +25,9 @@ export const getDoc: Get = reference => { * @returns A `Promise` resolved with a `DocumentSnapshot` containing the * current document contents. */ -// @ts-expect-error -export const getDocFromCache: Get = reference => { - return getDocFromCache_( - // @ts-expect-error - reference - ) -} +export const getDocFromCache = ((reference: OriDocumentReference) => { + return getDocFromCache_(reference) as Promise> +}) as Get /** * Reads the document referred to by this `DocumentReference` from the server. * Returns an error if the network is not available. @@ -43,10 +35,6 @@ export const getDocFromCache: Get = reference => { * @returns A `Promise` resolved with a `DocumentSnapshot` containing the * current document contents. */ -// @ts-expect-error -export const getDocFromServer: Get = async reference => { - return getDocFromServer_( - // @ts-expect-error - reference - ) -} +export const getDocFromServer = ((reference: OriDocumentReference) => { + return getDocFromServer_(reference) as Promise> +}) as Get diff --git a/src/operations/getDocs.ts b/src/operations/getDocs.ts index 0d3a07a..466a2b2 100644 --- a/src/operations/getDocs.ts +++ b/src/operations/getDocs.ts @@ -3,7 +3,7 @@ import { getDocsFromCache as getDocsFromCache_, getDocsFromServer as getDocsFromServer_, } from 'firebase/firestore' -import { MetaType, Query, QuerySnapshot } from '../types' +import { MetaType, Query, QuerySnapshot, OriQuery } from '../types' /** * Executes the query and returns the results as a `QuerySnapshot`. @@ -16,10 +16,7 @@ import { MetaType, Query, QuerySnapshot } from '../types' * @returns A `Promise` that will be resolved with the results of the query. */ export const getDocs = (query: Query) => { - return getDocs_( - // @ts-expect-error - query - ) as unknown as Promise> + return getDocs_(query as OriQuery) as unknown as Promise> } /** @@ -29,10 +26,9 @@ export const getDocs = (query: Query) => { * @returns A `Promise` that will be resolved with the results of the query. */ export const getDocsFromCache = (query: Query) => { - return getDocsFromCache_( - // @ts-expect-error - query - ) as unknown as Promise> + return getDocsFromCache_(query as OriQuery) as unknown as Promise< + QuerySnapshot + > } /** @@ -42,8 +38,7 @@ export const getDocsFromCache = (query: Query) => { * @returns A `Promise` that will be resolved with the results of the query. */ export const getDocsFromServer = (query: Query) => { - return getDocsFromServer_( - // @ts-expect-error - query - ) as unknown as Promise> + return getDocsFromServer_(query as OriQuery) as unknown as Promise< + QuerySnapshot + > } diff --git a/src/operations/setDoc.ts b/src/operations/setDoc.ts index 676ea28..0cbe4d2 100644 --- a/src/operations/setDoc.ts +++ b/src/operations/setDoc.ts @@ -15,16 +15,12 @@ Writes to the document referred to by this DocumentReference. If the document do @param options - An object to configure the set behavior. -@returns -A Promise resolved once the data has been successfully written to the backend (note that it won't resolve while you're offline). +@returns A Promise resolved once the data has been successfully written to the backend (note that it won't resolve while you're offline). */ export const setDoc = (( reference: OriDocumentReference, data: OriDocumentData, options?: OriSetOptions ) => { - const ref = options - ? setDoc_(reference, data, options) - : setDoc_(reference, data) - return ref -}) as unknown as Set // const setDoc:Set = .... type mismatched though + return options ? setDoc_(reference, data, options) : setDoc_(reference, data) +}) as Set // const setDoc:Set = .... type mismatched though diff --git a/src/operations/updateDoc.ts b/src/operations/updateDoc.ts index 8b5b2bb..d6c6eb4 100644 --- a/src/operations/updateDoc.ts +++ b/src/operations/updateDoc.ts @@ -10,15 +10,12 @@ import { flatten } from '../utils' @param data An object containing the fields and values with which to update the document. Fields can contain dots to reference nested fields within the document. - @returns - A Promise resolved once the data has been successfully written to the backend (note that it won't resolve while you're offline). + @returns A Promise resolved once the data has been successfully written to the backend (note that it won't resolve while you're offline). */ export const updateDoc = (( reference: OriDocumentReference, data: Record ) => { - const ref = - // @ts-expect-error - updateDoc_(reference, flatten(data)) // ! testing messed up the type, weird - return ref -}) as unknown as Update + // @ts-expect-error + return updateDoc_(reference, flatten(data)) +}) as Update diff --git a/src/queryClauses/where.ts b/src/queryClauses/where.ts index 30575a8..5fe4303 100644 --- a/src/queryClauses/where.ts +++ b/src/queryClauses/where.ts @@ -45,12 +45,7 @@ export const where = < fieldPath: fieldPath as string, opStr, value, - ref: where_( - // @ts-expect-error - fieldPath, - opStr, - newValue - ), + ref: where_(fieldPath as string, opStr, newValue), } as WhereConstraint< T, FieldPath extends DocumentId ? __name__ : FieldPath, diff --git a/src/transaction/delete.ts b/src/transaction/delete.ts index 9c2f9da..0455e01 100644 --- a/src/transaction/delete.ts +++ b/src/transaction/delete.ts @@ -2,12 +2,9 @@ import { OriDocumentReference, OriTransaction, TransactionDelete, - DocumentReference, - MetaType, } from '../types' -export const deleteCreator = ((transaction: OriTransaction) => - (reference: DocumentReference) => { - const ref = transaction.delete(reference as unknown as OriDocumentReference) - return ref - }) as unknown as (transaction: OriTransaction) => TransactionDelete +export const deleteCreator = (transaction: OriTransaction) => + ((reference: OriDocumentReference) => { + return transaction.delete(reference) as unknown + }) as TransactionDelete diff --git a/src/transaction/get.ts b/src/transaction/get.ts index 27544c8..ff850b6 100644 --- a/src/transaction/get.ts +++ b/src/transaction/get.ts @@ -1,11 +1,6 @@ import { OriTransaction, Get, OriDocumentReference } from '../types' -export const getCreator = - (transaction: OriTransaction): Get => - // @ts-expect-error - async reference => { - const ref = await transaction.get( - reference as unknown as OriDocumentReference - ) - return ref - } +export const getCreator = (transaction: OriTransaction) => + ((reference: OriDocumentReference) => { + return transaction.get(reference) as unknown + }) as Get diff --git a/src/transaction/set.ts b/src/transaction/set.ts index 0ca5fdf..7dfcae5 100644 --- a/src/transaction/set.ts +++ b/src/transaction/set.ts @@ -6,16 +6,15 @@ import { OriSetOptions, } from '../types' -export const setCreator = ((transaction: OriTransaction) => - ( +export const setCreator = (transaction: OriTransaction) => + (( reference: OriDocumentReference, data: OriDocumentData, options?: OriSetOptions ) => { - const ref = options - ? transaction.set(reference, data, options) - : transaction.set(reference, data) - return ref - }) as unknown as setCreator - -type setCreator = (transaction: OriTransaction) => TransactionSet + return ( + options + ? transaction.set(reference, data, options) + : transaction.set(reference, data) + ) as unknown + }) as TransactionSet diff --git a/src/transaction/update.ts b/src/transaction/update.ts index 453ff52..2d6b704 100644 --- a/src/transaction/update.ts +++ b/src/transaction/update.ts @@ -5,12 +5,10 @@ import { } from '../types' import { flatten } from '../utils' -export const updateCreator = ((transaction: OriTransaction) => - (reference: OriDocumentReference, data: Record) => { - const ref = transaction.update( +export const updateCreator = (transaction: OriTransaction) => + ((reference: OriDocumentReference, data: Record) => { + return transaction.update( reference, - // @ts-expect-error - flatten(data) - ) - return ref - }) as unknown as (transaction: OriTransaction) => TransactionUpdate + flatten(data) as Record + ) as unknown + }) as TransactionUpdate diff --git a/src/types/alias.ts b/src/types/alias.ts index a49bdb5..08a260e 100644 --- a/src/types/alias.ts +++ b/src/types/alias.ts @@ -5,6 +5,8 @@ import { OriSnapshotListenOptions, OriDocumentChangeType, OriFirestoreTesting, + OriUnsubscribe, + OriFirestoreError, } from './ori' export type Firestore = OriFirestore export type FirestoreTesting = OriFirestoreTesting @@ -13,3 +15,5 @@ export type SnapshotMetadata = OriSnapshotMetadata export type SnapshotOptions = OriSnapshotOptions export type SnapshotListenOptions = OriSnapshotListenOptions export type DocumentChangeType = OriDocumentChangeType +export type Unsubscribe = OriUnsubscribe +export type FirestoreError = OriFirestoreError diff --git a/src/types/metaTypeCreator.test.ts b/src/types/metaTypeCreator.test.ts index 67cca69..8182b82 100644 --- a/src/types/metaTypeCreator.test.ts +++ b/src/types/metaTypeCreator.test.ts @@ -33,7 +33,7 @@ describe('test Firelord type', () => { 'A', string, never, - { allFieldsPossiblyUndefined: true } + { allFieldsPossiblyReadAsUndefined: true } > type ExpectedRead = { a: 1 | null | undefined diff --git a/src/types/metaTypeCreator.ts b/src/types/metaTypeCreator.ts index d89b88d..ff6a02f 100644 --- a/src/types/metaTypeCreator.ts +++ b/src/types/metaTypeCreator.ts @@ -43,15 +43,17 @@ export type MetaTypeCreator< DocID extends string = string, Parent extends MetaType | null = null, Settings extends { - allFieldsPossiblyUndefined?: boolean + allFieldsPossiblyReadAsUndefined?: boolean banNull?: boolean - } = { allFieldsPossiblyUndefined: false; banNull: false } + } = { allFieldsPossiblyReadAsUndefined: false; banNull: false } > = { base: Base read: { [J in keyof RecursiveReplaceUnionInvolveObjectTypeWithErrorMsg]-?: ReadConverter< RecursiveReplaceUnionInvolveObjectTypeWithErrorMsg[J], - Settings['allFieldsPossiblyUndefined'] extends true ? undefined : never, + Settings['allFieldsPossiblyReadAsUndefined'] extends true + ? undefined + : never, Settings['banNull'] extends true ? null : never > } @@ -119,18 +121,25 @@ export type MetaTypeCreator< type ReadConverterArray< T, - AllFieldsPossiblyUndefined, + allFieldsPossiblyReadAsUndefined, BannedTypes, InArray extends boolean > = NoDirectNestedArray extends T ? T extends (infer A)[] ? - | ReadConverterArray[] - | (InArray extends true ? never : AllFieldsPossiblyUndefined) + | ReadConverterArray< + A, + allFieldsPossiblyReadAsUndefined, + BannedTypes, + true + >[] + | (InArray extends true ? never : allFieldsPossiblyReadAsUndefined) : T extends FieldValues ? ErrorFieldValueInArray : T extends Date | OriTimestamp - ? OriTimestamp | (InArray extends true ? never : AllFieldsPossiblyUndefined) + ? + | OriTimestamp + | (InArray extends true ? never : allFieldsPossiblyReadAsUndefined) : T extends PossiblyReadAsUndefined ? InArray extends true ? ErrorPossiblyUndefinedAsArrayElement @@ -140,28 +149,30 @@ type ReadConverterArray< | { [K in keyof T]-?: ReadConverterArray< T[K], - AllFieldsPossiblyUndefined, + allFieldsPossiblyReadAsUndefined, BannedTypes, false > } - | (InArray extends true ? never : AllFieldsPossiblyUndefined) - : NoUndefinedAndBannedTypes | AllFieldsPossiblyUndefined - : NoUndefinedAndBannedTypes | AllFieldsPossiblyUndefined + | (InArray extends true ? never : allFieldsPossiblyReadAsUndefined) + : + | NoUndefinedAndBannedTypes + | allFieldsPossiblyReadAsUndefined + : NoUndefinedAndBannedTypes | allFieldsPossiblyReadAsUndefined -type ReadConverter = +type ReadConverter = NoDirectNestedArray extends T ? T extends (infer A)[] ? | ReadConverterArray< A, - AllFieldsPossiblyUndefined, + allFieldsPossiblyReadAsUndefined, BannedTypes, true >[] - | AllFieldsPossiblyUndefined + | allFieldsPossiblyReadAsUndefined : T extends ServerTimestamp | Date | OriTimestamp - ? OriTimestamp | AllFieldsPossiblyUndefined + ? OriTimestamp | allFieldsPossiblyReadAsUndefined : T extends DeleteField | PossiblyReadAsUndefined ? undefined : T extends UnassignedAbleFieldValue @@ -171,13 +182,17 @@ type ReadConverter = | { [K in keyof T]-?: ReadConverter< T[K], - AllFieldsPossiblyUndefined, + allFieldsPossiblyReadAsUndefined, BannedTypes > } - | AllFieldsPossiblyUndefined - : NoUndefinedAndBannedTypes | AllFieldsPossiblyUndefined - : NoUndefinedAndBannedTypes | AllFieldsPossiblyUndefined + | allFieldsPossiblyReadAsUndefined + : + | NoUndefinedAndBannedTypes + | allFieldsPossiblyReadAsUndefined + : + | NoUndefinedAndBannedTypes + | allFieldsPossiblyReadAsUndefined type CompareConverterArray = NoDirectNestedArray extends T ? T extends (infer A)[] diff --git a/src/types/ori.ts b/src/types/ori.ts index f2e8c08..2c5b07e 100644 --- a/src/types/ori.ts +++ b/src/types/ori.ts @@ -6,26 +6,6 @@ export type OriFirestoreTesting = ReturnType export type OriFirebaseFirestore = typeof import('firebase/firestore') -export type OriDoc = OriFirebaseFirestore['doc'] - -export type OriCollection = OriFirebaseFirestore['collection'] - -export type OriCollectionGroup = OriFirebaseFirestore['collectionGroup'] - -export type OriSetDoc = OriFirebaseFirestore['setDoc'] - -export type OriGetDoc = OriFirebaseFirestore['getDoc'] - -export type OriAddDoc = OriFirebaseFirestore['addDoc'] - -export type OriDeleteDoc = OriFirebaseFirestore['deleteDoc'] - -export type OriUpdateDoc = OriFirebaseFirestore['updateDoc'] - -export type OriRunTransaction = OriFirebaseFirestore['runTransaction'] - -export type OriFieldValue = import('firebase/firestore').FieldValue - export type OriDocumentData = import('firebase/firestore').DocumentData export type OriSetOptions = import('firebase/firestore').SetOptions From 9237764dfad2a315c143060e38d0f5bcc2a0b33f Mon Sep 17 00:00:00 2001 From: tylim Date: Tue, 19 Jul 2022 05:49:24 +0800 Subject: [PATCH 3/3] - remove onSnapshot onCompletion parameter --- CHANGELOG.md | 1 + package-lock.json | 4 +-- package.json | 2 +- src/onSnapshot/onSnapshot.test.ts | 3 --- src/onSnapshot/onSnapshot.ts | 43 +++---------------------------- 5 files changed, 7 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8d69b0..4b8bd54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v1.5.0 19-July-2022 - rename setting `allFieldsPossiblyUndefined` as `allFieldsPossiblyReadAsUndefined` +- remove onSnapshot onCompletion parameter ## v1.3.0 6-May-2022 diff --git a/package-lock.json b/package-lock.json index caced0d..5efa672 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firelordjs", - "version": "1.4.4", + "version": "1.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "firelordjs", - "version": "1.4.4", + "version": "1.5.0", "license": "MIT", "devDependencies": { "@babel/preset-env": "^7.17.10", diff --git a/package.json b/package.json index 9010bc0..c133365 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "test": "firebase emulators:exec --only firestore \"rm -rf coverage && jest --forceExit\"", "parcel": "npm un firebase && npm i firebase && rm -rf dist && tsc --emitDeclarationOnly true && parcel build && npm i -D firebase", "build": "rm -rf dist && tsc", - "link": "npm link && npm link firelordjs", + "link": "npm unlink firelordjs && npm link && npm link firelordjs", "dev": "---------------------dev------------------------", "d-link": "npm run build && npm run link", "d-test": "tsc && npm test", diff --git a/src/onSnapshot/onSnapshot.test.ts b/src/onSnapshot/onSnapshot.test.ts index 4c2aa1b..0cdc253 100644 --- a/src/onSnapshot/onSnapshot.test.ts +++ b/src/onSnapshot/onSnapshot.test.ts @@ -59,9 +59,6 @@ describe('test onSnapshot', () => { unsub() done() }, - () => { - // - }, () => { // } diff --git a/src/onSnapshot/onSnapshot.ts b/src/onSnapshot/onSnapshot.ts index d09e517..70acd22 100644 --- a/src/onSnapshot/onSnapshot.ts +++ b/src/onSnapshot/onSnapshot.ts @@ -27,64 +27,27 @@ export const isOptions = ( export const onSnapshot: OnSnapshot = ( reference, onNext, - onError, - onCompletion?: (() => void) | OriSnapshotListenOptions, + onError?: ((error: FirestoreError) => void) | OriSnapshotListenOptions, options?: OriSnapshotListenOptions ) => { const newOnError = isOptions(onError) ? undefined : onError - const newOnCompletion = isOptions(onCompletion) ? undefined : onCompletion - const newOptions = - options || - (isOptions(onError) ? onError : undefined) || - (isOptions(onCompletion) ? onCompletion : undefined) + const newOptions = options || (isOptions(onError) ? onError : undefined) return newOptions ? onSnapshot_(reference as OriQuery, newOptions, { // @ts-expect-error next: onNext, error: newOnError, - complete: newOnCompletion, }) : onSnapshot_( reference as OriQuery, // @ts-expect-error onNext, - newOnError, - newOnCompletion + newOnError ) } type OnSnapshot = { - /** - * Attaches a listener for `DocumentSnapshot` events. You may either pass - * individual `onNext` and `onError` callbacks or pass a single observer - * object with `next` and `error` callbacks. - * - * NOTE: Although an `onCompletion` callback can be provided, it will - * never be called because the snapshot stream is never-ending. - * - * @param reference - A reference to the document to listen to. - * @param onNext - A callback to be called every time a new `DocumentSnapshot` - * is available. - * @param onError - An optional callback to be called if the listen fails or is - * cancelled. No further callbacks will occur. - * @param onCompletion - optional callback, but will not be called since streams are - * never ending. - * @param options - Options controlling the listen behavior. - * @returns An unsubscribe function that can be called to cancel - * the snapshot listener. - */ - | DocumentReference>( - reference: Ref extends never ? Ref : Query | DocumentReference, - onNext: ( - snapshot: Ref extends DocumentReference - ? DocumentSnapshot - : QuerySnapshot - ) => void, - onError?: (error: FirestoreError) => void, - onCompletion?: () => void, - options?: SnapshotListenOptions - ): Unsubscribe /** * Attaches a listener for `DocumentSnapshot` events. You may either pass * individual `onNext` and `onError` callbacks or pass a single observer