@@ -108,7 +108,7 @@ export function _instanceWithOptions(
108
108
*/
109
109
export class InstanceBuilder {
110
110
/** @hidden */
111
- constructor ( private instance : string , private options : DeploymentOptions ) { }
111
+ constructor ( private instance : string , private options : DeploymentOptions ) { }
112
112
113
113
/**
114
114
* @return Firebase Realtime Database reference builder interface.
@@ -134,9 +134,9 @@ export function _refWithOptions(
134
134
if ( ! databaseURL ) {
135
135
throw new Error (
136
136
'Missing expected firebase config value databaseURL, ' +
137
- 'config is actually' +
138
- JSON . stringify ( firebaseConfig ( ) ) +
139
- '\n If you are unit testing, please set process.env.FIREBASE_CONFIG'
137
+ 'config is actually' +
138
+ JSON . stringify ( firebaseConfig ( ) ) +
139
+ '\n If you are unit testing, please set process.env.FIREBASE_CONFIG'
140
140
) ;
141
141
}
142
142
@@ -174,7 +174,7 @@ export class RefBuilder {
174
174
private apps : apps . Apps ,
175
175
private triggerResource : ( ) => string ,
176
176
private options : DeploymentOptions
177
- ) { }
177
+ ) { }
178
178
179
179
/**
180
180
* Event handler that fires every time a Firebase Realtime Database write
@@ -325,7 +325,7 @@ export function extractInstanceAndPath(
325
325
if ( ! match ) {
326
326
throw new Error (
327
327
`Unexpected resource string for Firebase Realtime Database event: ${ resource } . ` +
328
- 'Expected string in the format of "projects/_/instances/{firebaseioSubdomain}/refs/{ref=**}"'
328
+ 'Expected string in the format of "projects/_/instances/{firebaseioSubdomain}/refs/{ref=**}"'
329
329
) ;
330
330
}
331
331
const [ , project , dbInstanceName , path ] = match ;
@@ -396,7 +396,7 @@ export class DataSnapshot {
396
396
// may be unpopulated in user's unit tests
397
397
throw new Error (
398
398
'Please supply a Firebase app in the constructor for DataSnapshot' +
399
- ' in order to use the .ref method.'
399
+ ' in order to use the .ref method.'
400
400
) ;
401
401
}
402
402
if ( ! this . _ref ) {
@@ -471,7 +471,16 @@ export class DataSnapshot {
471
471
* @return `true` if this `DataSnapshot` contains any data; otherwise, `false`.
472
472
*/
473
473
exists ( ) : boolean {
474
- return ! _ . isNull ( this . val ( ) ) ;
474
+ const val = this . val ( ) ;
475
+ if ( _ . isNull ( val ) ) {
476
+ // Null value
477
+ return false ;
478
+ }
479
+ if ( ( _ . isObjectLike ( val ) || _ . isArray ( val ) ) && _ . isEmpty ( val ) ) {
480
+ // Empty object/array
481
+ return false ;
482
+ }
483
+ return true
475
484
}
476
485
477
486
/**
@@ -512,7 +521,7 @@ export class DataSnapshot {
512
521
*/
513
522
forEach ( action : ( a : DataSnapshot ) => boolean | void ) : boolean {
514
523
const val = this . val ( ) ;
515
- if ( _ . isPlainObject ( val ) ) {
524
+ if ( _ . isObjectLike ( val ) || _ . isArray ( val ) ) {
516
525
return _ . some (
517
526
val ,
518
527
( value , key : string ) => action ( this . child ( key ) ) === true
@@ -546,7 +555,7 @@ export class DataSnapshot {
546
555
*/
547
556
hasChildren ( ) : boolean {
548
557
const val = this . val ( ) ;
549
- return _ . isPlainObject ( val ) && _ . keys ( val ) . length > 0 ;
558
+ return ( _ . isObjectLike ( val ) || _ . isArray ( val ) ) && ! _ . isEmpty ( val ) ;
550
559
}
551
560
552
561
/**
@@ -556,7 +565,7 @@ export class DataSnapshot {
556
565
*/
557
566
numChildren ( ) : number {
558
567
const val = this . val ( ) ;
559
- return _ . isPlainObject ( val ) ? Object . keys ( val ) . length : 0 ;
568
+ return ( _ . isObjectLike ( val ) || _ . isArray ( val ) ) ? _ . keys ( val ) . length : 0 ;
560
569
}
561
570
562
571
/**
@@ -588,7 +597,12 @@ export class DataSnapshot {
588
597
continue ;
589
598
}
590
599
const childNode = node [ key ] ;
591
- obj [ key ] = this . _checkAndConvertToArray ( childNode ) ;
600
+ const v = this . _checkAndConvertToArray ( childNode ) ;
601
+ if ( v === null ) {
602
+ // Empty child node
603
+ continue ;
604
+ }
605
+ obj [ key ] = v ;
592
606
numKeys ++ ;
593
607
const integerRegExp = / ^ ( 0 | [ 1 - 9 ] \d * ) $ / ;
594
608
if ( allIntegerKeys && integerRegExp . test ( key ) ) {
@@ -598,6 +612,11 @@ export class DataSnapshot {
598
612
}
599
613
}
600
614
615
+ if ( numKeys === 0 ) {
616
+ // Empty node
617
+ return null ;
618
+ }
619
+
601
620
if ( allIntegerKeys && maxKey < 2 * numKeys ) {
602
621
// convert to array.
603
622
const array : any = [ ] ;
0 commit comments