File tree 4 files changed +55
-13
lines changed 4 files changed +55
-13
lines changed Original file line number Diff line number Diff line change 4
4
- [ changed] Changed ` get() ` to only make 1 attempt to reach the backend before
5
5
returning cached data, potentially reducing delays while offline. Previously
6
6
it would make 2 attempts, to work around a backend bug.
7
+ - [ fixed] Fixed an issue that caused us to drop empty objects from calls to
8
+ ` set(..., { merge: true }) ` .
7
9
8
10
# 0.7.3
9
11
- [ changed] Changed the internal handling for locally updated documents that
Original file line number Diff line number Diff line change @@ -539,15 +539,25 @@ export class UserDataConverter {
539
539
540
540
private parseObject ( obj : Dict < AnyJs > , context : ParseContext ) : FieldValue {
541
541
let result = new SortedMap < string , FieldValue > ( primitiveComparator ) ;
542
- objUtils . forEach ( obj , ( key : string , val : AnyJs ) => {
543
- const parsedValue = this . parseData (
544
- val ,
545
- context . childContextForField ( key )
546
- ) ;
547
- if ( parsedValue != null ) {
548
- result = result . insert ( key , parsedValue ) ;
542
+
543
+ if ( objUtils . isEmpty ( obj ) ) {
544
+ // If we encounter an empty object, we explicitly add it to the update
545
+ // mask to ensure that the server creates a map entry.
546
+ if ( context . path && context . path . length > 0 ) {
547
+ context . fieldMask . push ( context . path ) ;
549
548
}
550
- } ) ;
549
+ } else {
550
+ objUtils . forEach ( obj , ( key : string , val : AnyJs ) => {
551
+ const parsedValue = this . parseData (
552
+ val ,
553
+ context . childContextForField ( key )
554
+ ) ;
555
+ if ( parsedValue != null ) {
556
+ result = result . insert ( key , parsedValue ) ;
557
+ }
558
+ } ) ;
559
+ }
560
+
551
561
return new ObjectValue ( result ) ;
552
562
}
553
563
Original file line number Diff line number Diff line change @@ -449,11 +449,13 @@ export class PatchMutation extends Mutation {
449
449
450
450
private patchObject ( data : ObjectValue ) : ObjectValue {
451
451
for ( const fieldPath of this . fieldMask . fields ) {
452
- const newValue = this . data . field ( fieldPath ) ;
453
- if ( newValue !== undefined ) {
454
- data = data . set ( fieldPath , newValue ) ;
455
- } else {
456
- data = data . delete ( fieldPath ) ;
452
+ if ( ! fieldPath . isEmpty ( ) ) {
453
+ const newValue = this . data . field ( fieldPath ) ;
454
+ if ( newValue !== undefined ) {
455
+ data = data . set ( fieldPath , newValue ) ;
456
+ } else {
457
+ data = data . delete ( fieldPath ) ;
458
+ }
457
459
}
458
460
}
459
461
return data ;
Original file line number Diff line number Diff line change @@ -188,6 +188,34 @@ apiDescribe('Database', persistence => {
188
188
} ) ;
189
189
} ) ;
190
190
191
+ it ( 'can merge empty object' , async ( ) => {
192
+ await withTestDoc ( persistence , async doc => {
193
+ const accumulator = new EventsAccumulator < firestore . DocumentSnapshot > ( ) ;
194
+ const unsubscribe = doc . onSnapshot ( accumulator . storeEvent ) ;
195
+ await accumulator
196
+ . awaitEvent ( )
197
+ . then ( ( ) => doc . set ( { } ) )
198
+ . then ( ( ) => accumulator . awaitEvent ( ) )
199
+ . then ( docSnapshot => expect ( docSnapshot . data ( ) ) . to . be . deep . equal ( { } ) )
200
+ . then ( ( ) => doc . set ( { a : { } } , { mergeFields : [ 'a' ] } ) )
201
+ . then ( ( ) => accumulator . awaitEvent ( ) )
202
+ . then ( docSnapshot =>
203
+ expect ( docSnapshot . data ( ) ) . to . be . deep . equal ( { a : { } } )
204
+ )
205
+ . then ( ( ) => doc . set ( { b : { } } , { merge : true } ) )
206
+ . then ( ( ) => accumulator . awaitEvent ( ) )
207
+ . then ( docSnapshot =>
208
+ expect ( docSnapshot . data ( ) ) . to . be . deep . equal ( { a : { } , b : { } } )
209
+ )
210
+ . then ( ( ) => doc . get ( { source : 'server' } ) )
211
+ . then ( docSnapshot => {
212
+ expect ( docSnapshot . data ( ) ) . to . be . deep . equal ( { a : { } , b : { } } ) ;
213
+ } ) ;
214
+
215
+ unsubscribe ( ) ;
216
+ } ) ;
217
+ } ) ;
218
+
191
219
it ( 'can delete field using merge' , ( ) => {
192
220
return withTestDoc ( persistence , doc => {
193
221
const initialData = {
You can’t perform that action at this time.
0 commit comments