Skip to content

Commit 8d1219c

Browse files
Throw when user data parsing fails
1 parent 72b0b8b commit 8d1219c

File tree

2 files changed

+59
-19
lines changed

2 files changed

+59
-19
lines changed

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

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import { hardAssert } from '../../../src/util/assert';
3939
import { DeleteMutation, Precondition } from '../../../src/model/mutation';
4040
import { PlatformSupport } from '../../../src/platform/platform';
4141
import { applyFirestoreDataConverter } from '../../../src/api/database';
42+
import { DatabaseId } from '../../../src/core/database_info';
4243

4344
/**
4445
* A reference to a particular document in a collection in the database.
@@ -312,21 +313,27 @@ export function setDoc<T>(
312313
options?: firestore.SetOptions
313314
): Promise<void> {
314315
const ref = tryCast(reference, DocumentReference);
315-
return ref.firestore._ensureClientConfigured().then(firestore => {
316-
const dataReader = newUserDataReader(firestore);
317316

318-
const [convertedValue] = applyFirestoreDataConverter(
319-
ref._converter,
320-
data,
321-
'setDoc'
322-
);
317+
const [convertedValue] = applyFirestoreDataConverter(
318+
ref._converter,
319+
data,
320+
'setDoc'
321+
);
323322

324-
const parsed = isMerge(options)
325-
? dataReader.parseMergeData('setDoc', convertedValue)
326-
: isMergeFields(options)
327-
? dataReader.parseMergeData('setDoc', convertedValue, options.mergeFields)
328-
: dataReader.parseSetData('setDoc', convertedValue);
323+
// Kick off configuring the client, which freezes the settings.
324+
const configureClient = ref.firestore._ensureClientConfigured();
325+
const dataReader = newUserDataReader(
326+
ref.firestore._databaseId,
327+
ref.firestore._settings!
328+
);
329329

330+
const parsed = isMerge(options)
331+
? dataReader.parseMergeData('setDoc', convertedValue)
332+
: isMergeFields(options)
333+
? dataReader.parseMergeData('setDoc', convertedValue, options.mergeFields)
334+
: dataReader.parseSetData('setDoc', convertedValue);
335+
336+
return configureClient.then(firestore => {
330337
return invokeCommitRpc(
331338
firestore._datastore,
332339
parsed.toMutations(ref._key, Precondition.none())
@@ -363,13 +370,14 @@ function isMergeFields(
363370
);
364371
}
365372

366-
function newUserDataReader(firestore: Required<Firestore>): UserDataReader {
367-
const serializer = PlatformSupport.getPlatform().newSerializer(
368-
firestore._databaseId
369-
);
373+
function newUserDataReader(
374+
databaseId: DatabaseId,
375+
settings: firestore.Settings
376+
): UserDataReader {
377+
const serializer = PlatformSupport.getPlatform().newSerializer(databaseId);
370378
return new UserDataReader(
371-
firestore._databaseId,
372-
!!firestore._settings.ignoreUndefinedProperties,
379+
databaseId,
380+
!!settings.ignoreUndefinedProperties,
373381
serializer
374382
);
375383
}

packages/firestore/lite/test/integration.test.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ import {
2323
getFirestore,
2424
initializeFirestore
2525
} from '../src/api/database';
26-
import { withTestDb, withTestDoc, withTestDocAndInitialData } from './helpers';
26+
import {
27+
withTestDb,
28+
withTestDbSettings,
29+
withTestDoc,
30+
withTestDocAndInitialData
31+
} from './helpers';
2732
import {
2833
parent,
2934
collection,
@@ -35,6 +40,10 @@ import {
3540
setDoc
3641
} from '../src/api/reference';
3742
import { FieldPath } from '../src/api/field_path';
43+
import {
44+
DEFAULT_PROJECT_ID,
45+
DEFAULT_SETTINGS
46+
} from '../../test/integration/util/settings';
3847

3948
describe('Firestore', () => {
4049
it('can provide setting', () => {
@@ -222,6 +231,29 @@ describe('setDoc()', () => {
222231
});
223232
});
224233
});
234+
235+
it("rejects 'undefined' by default", () => {
236+
return withTestDoc(async docRef => {
237+
expect(() => {
238+
setDoc(docRef, { val: undefined });
239+
}).to.throw(
240+
'Function setDoc() called with invalid data. Unsupported field value: undefined (found in field val)'
241+
);
242+
});
243+
});
244+
245+
it("ignores 'undefined' when enabled", () => {
246+
return withTestDbSettings(
247+
DEFAULT_PROJECT_ID,
248+
{ ...DEFAULT_SETTINGS, ignoreUndefinedProperties: true },
249+
async db => {
250+
const docRef = doc(collection(db, 'test-collection'));
251+
await setDoc(docRef, { val: undefined });
252+
const docSnap = await getDoc(docRef);
253+
expect(docSnap.data()).to.deep.equal({});
254+
}
255+
);
256+
});
225257
});
226258

227259
describe('DocumentSnapshot', () => {

0 commit comments

Comments
 (0)