Skip to content

Commit 9533688

Browse files
authored
handle ignoreUndefinedProperties in set(merge: true) (#4347)
Previously any field in the document would be propagated into the FieldMask regardless of whether or not it had an undefined value, which led to the client acting as if the user had passed FieldValue.delete(), which wasn't intended. Fixes googleapis/nodejs-firestore#1392 for the JS SDK.
1 parent 269c918 commit 9533688

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

.changeset/silent-cars-burn.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@firebase/firestore': patch
3+
---
4+
5+
handle `ignoreUndefinedProperties` in `set({ merge: true })`. Previously this would behave as if the undefined value were `FieldValue.delete()`, which wasn't intended.

packages/firestore/src/api/user_data_reader.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,11 @@ export function parseData(
738738
// context.fieldMask and we return null as our parsing result.
739739
parseSentinelFieldValue(input, context);
740740
return null;
741+
} else if (input === undefined && context.ignoreUndefinedProperties) {
742+
// If the input is undefined it can never participate in the fieldMask, so
743+
// don't handle this below. If `ignoreUndefinedProperties` is false,
744+
// `parseScalarValue` will reject an undefined value.
745+
return null;
741746
} else {
742747
// If context.path is null we are inside an array and we don't support
743748
// field mask paths more granular than the top-level array.
@@ -896,8 +901,6 @@ function parseScalarValue(
896901
value._key.path
897902
)
898903
};
899-
} else if (value === undefined && context.ignoreUndefinedProperties) {
900-
return null;
901904
} else {
902905
throw context.createError(
903906
`Unsupported field value: ${valueDescription(value)}`

packages/firestore/test/integration/api/fields.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,15 @@ apiDescribe('`undefined` properties', (persistence: boolean) => {
398398
});
399399
});
400400

401+
it('are ignored in set({ merge: true })', () => {
402+
return withTestDocAndSettings(persistence, settings, async doc => {
403+
await doc.set({ foo: 'foo', bar: 'unchanged' });
404+
await doc.set({ foo: 'foo', bar: undefined }, { merge: true });
405+
const docSnap = await doc.get();
406+
expect(docSnap.data()).to.deep.equal({ foo: 'foo', bar: 'unchanged' });
407+
});
408+
});
409+
401410
it('are ignored in update()', () => {
402411
return withTestDocAndSettings(persistence, settings, async doc => {
403412
await doc.set({});

0 commit comments

Comments
 (0)