diff --git a/.changeset/silly-seahorses-jump.md b/.changeset/silly-seahorses-jump.md new file mode 100644 index 00000000000..b4220d59c21 --- /dev/null +++ b/.changeset/silly-seahorses-jump.md @@ -0,0 +1,5 @@ +--- +'@firebase/firestore': minor +--- + +Add addDoc function overloading to accept DocumentRef diff --git a/common/api-review/firestore.api.md b/common/api-review/firestore.api.md index 34b56b97f21..90a7a216c9d 100644 --- a/common/api-review/firestore.api.md +++ b/common/api-review/firestore.api.md @@ -9,6 +9,9 @@ import { FirebaseApp } from '@firebase/app'; import { FirebaseError } from '@firebase/util'; import { LogLevelString as LogLevel } from '@firebase/logger'; +// @public +export function addDoc(reference: DocumentReference, data: WithFieldValue): Promise>; + // @public export function addDoc(reference: CollectionReference, data: WithFieldValue): Promise>; diff --git a/packages/firestore/src/api/reference_impl.ts b/packages/firestore/src/api/reference_impl.ts index e730fb40da7..c65660c5729 100644 --- a/packages/firestore/src/api/reference_impl.ts +++ b/packages/firestore/src/api/reference_impl.ts @@ -438,6 +438,20 @@ export function deleteDoc( return executeWrite(firestore, mutations); } +/** + * Add a new document to specified `DocReference` with the given data. + * + * @param reference - A reference to the document to add. + * @param data - An Object containing the data for the new document. + * @returns A `Promise` resolved with a `DocumentReference` pointing to the + * newly created document after it has been written to the backend (Note that it + * won't resolve while you're offline). + * @throws FirestoreError if the document already exists. + */ +export function addDoc( + reference: DocumentReference, + data: WithFieldValue +): Promise>; /** * Add a new document to specified `CollectionReference` with the given data, * assigning it a document ID automatically. @@ -451,10 +465,17 @@ export function deleteDoc( export function addDoc( reference: CollectionReference, data: WithFieldValue +): Promise>; +export function addDoc( + reference: + | CollectionReference + | DocumentReference, + data: WithFieldValue ): Promise> { const firestore = cast(reference.firestore, Firestore); - const docRef = doc(reference); + const docRef = + reference instanceof DocumentReference ? reference : doc(reference); const convertedValue = applyFirestoreDataConverter(reference.converter, data); const dataReader = newUserDataReader(reference.firestore); diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index 81dc7362a22..a1525b2ba67 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -16,7 +16,7 @@ */ import { deleteApp } from '@firebase/app'; -import { Deferred } from '@firebase/util'; +import { Deferred, FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import chaiAsPromised from 'chai-as-promised'; @@ -106,6 +106,33 @@ apiDescribe('Database', persistence => { }); }); + it('can add a document with DocRef', () => { + return withTestCollection(persistence, {}, async coll => { + const docRef = doc(coll, 'foo'); + await addDoc(docRef, { a: 'a' }); + const docSnapshot = await getDoc(docRef); + expect(docSnapshot.data()).to.be.deep.equal({ a: 'a' }); + }); + }); + + it('can add a document with CollectionRef', () => { + return withTestCollection(persistence, {}, async coll => { + const docRef = await addDoc(coll, { a: 'a' }); + const docSnapshot = await getDoc(docRef); + expect(docSnapshot.data()).to.be.deep.equal({ a: 'a' }); + }); + }); + + it("can't add a document with duplicated id", () => { + return withTestDoc(persistence, async docRef => { + await addDoc(docRef, { a: 'a' }); + await expect(addDoc(docRef, { a: 'a' })).to.be.rejectedWith( + FirebaseError, + 'Document already exists:' + ); + }); + }); + it('can delete a document', () => { // TODO(#1865): This test fails with node:persistence against Prod return withTestDoc(persistence, docRef => {