diff --git a/.changeset/tame-donuts-relate.md b/.changeset/tame-donuts-relate.md new file mode 100644 index 00000000000..eb1c70bb95f --- /dev/null +++ b/.changeset/tame-donuts-relate.md @@ -0,0 +1,5 @@ +--- +'@firebase/firestore': patch +--- + +Fixed a bug where CollectionReference.add() called FirestoreDataConverter.toFirestore() twice intead of once (#3742). diff --git a/packages/firestore/exp/src/api/transaction.ts b/packages/firestore/exp/src/api/transaction.ts index 8f69a4016c0..e29448780ef 100644 --- a/packages/firestore/exp/src/api/transaction.ts +++ b/packages/firestore/exp/src/api/transaction.ts @@ -29,7 +29,8 @@ import { Transaction as InternalTransaction } from '../../../src/core/transactio import { validateReference } from '../../../lite/src/api/write_batch'; import { getDatastore } from '../../../lite/src/api/components'; -export class Transaction extends LiteTransaction +export class Transaction + extends LiteTransaction implements firestore.Transaction { // This class implements the same logic as the Transaction API in the Lite SDK // but is subclassed in order to return its own DocumentSnapshot types. diff --git a/packages/firestore/lite/src/api/field_value.ts b/packages/firestore/lite/src/api/field_value.ts index 05b35b6ef8c..33aa96b3a67 100644 --- a/packages/firestore/lite/src/api/field_value.ts +++ b/packages/firestore/lite/src/api/field_value.ts @@ -30,7 +30,8 @@ import { ParseContext } from '../../../src/api/user_data_reader'; import { FieldTransform } from '../../../src/model/mutation'; /** The public FieldValue class of the lite API. */ -export abstract class FieldValue extends SerializableFieldValue +export abstract class FieldValue + extends SerializableFieldValue implements firestore.FieldValue {} /** diff --git a/packages/firestore/src/api/database.ts b/packages/firestore/src/api/database.ts index c7f12ef6dc9..df9d16ad5ea 100644 --- a/packages/firestore/src/api/database.ts +++ b/packages/firestore/src/api/database.ts @@ -2379,8 +2379,17 @@ export class CollectionReference ? this._converter.toFirestore(value) : value; validateArgType('CollectionReference.add', 'object', 1, convertedValue); + const docRef = this.doc(); - return docRef.set(value).then(() => docRef); + + // Call set() with the converted value directly to avoid calling toFirestore() a second time. + return new DocumentReference( + (docRef as DocumentReference)._key, + this.firestore, + null + ) + .set(convertedValue) + .then(() => docRef); } withConverter(