@@ -109,6 +109,9 @@ export class RealtimeHandler {
109
109
} ) ;
110
110
}
111
111
112
+ /**
113
+ * Increase the backoff duration with a new end time based on Retry Interval.
114
+ */
112
115
private async updateBackoffMetadataWithRetryInterval (
113
116
retryIntervalSeconds : number
114
117
) : Promise < void > {
@@ -139,8 +142,9 @@ export class RealtimeHandler {
139
142
} ;
140
143
141
144
/**
142
- * Stops the real-time HTTP connection by aborting the in-progress fetch request
143
- * and canceling the stream reader if they exist.
145
+ * Closes the realtime HTTP connection.
146
+ * Note: This method is designed to be called only once at a time.
147
+ * If a call is already in progress, subsequent calls will be ignored.
144
148
*/
145
149
private async closeRealtimeHttpConnection ( ) : Promise < void > {
146
150
if ( this . isClosingConnection ) {
@@ -262,6 +266,11 @@ export class RealtimeHandler {
262
266
this . isConnectionActive = connectionRunning ;
263
267
}
264
268
269
+ /**
270
+ * Combines the check and set operations to prevent multiple asynchronous
271
+ * calls from redundantly starting an HTTP connection. This ensures that
272
+ * only one attempt is made at a time.
273
+ */
265
274
private checkAndSetHttpConnectionFlagIfNotRunning ( ) : boolean {
266
275
const canMakeConnection = this . canEstablishStreamConnection ( ) ;
267
276
if ( canMakeConnection ) {
@@ -274,9 +283,12 @@ export class RealtimeHandler {
274
283
fetchResponse : FetchResponse ,
275
284
lastKnownVersion : number
276
285
) : boolean {
286
+ // If there is a config, make sure its version is >= the last known version.
277
287
if ( fetchResponse . config != null && fetchResponse . templateVersion ) {
278
288
return fetchResponse . templateVersion >= lastKnownVersion ;
279
289
}
290
+ // If there isn't a config, return true if the fetch was successful and backend had no update.
291
+ // Else, it returned an out of date config.
280
292
return this . storageCache . getLastFetchStatus ( ) === 'success' ;
281
293
}
282
294
@@ -302,6 +314,10 @@ export class RealtimeHandler {
302
314
this . observers . forEach ( observer => observer . next ( configUpdate ) ) ;
303
315
}
304
316
317
+ /**
318
+ * Compares two configuration objects and returns a set of keys that have changed.
319
+ * A key is considered changed if it's new, removed, or has a different value.
320
+ */
305
321
private getChangedParams (
306
322
newConfig : FirebaseRemoteConfigObject ,
307
323
oldConfig : FirebaseRemoteConfigObject
@@ -420,6 +436,13 @@ export class RealtimeHandler {
420
436
await this . fetchLatestConfig ( remainingAttempts , targetVersion ) ;
421
437
}
422
438
439
+ /**
440
+ * Processes a stream of real-time messages for configuration updates.
441
+ * This method reassembles fragmented messages, validates and parses the JSON,
442
+ * and automatically fetches a new config if a newer template version is available.
443
+ * It also handles server-specified retry intervals and propagates errors for
444
+ * invalid messages or when real-time updates are disabled.
445
+ */
423
446
private async handleNotifications (
424
447
reader : ReadableStreamDefaultReader
425
448
) : Promise < void > {
@@ -527,13 +550,6 @@ export class RealtimeHandler {
527
550
'Real-time connection was closed due to an exception.'
528
551
) ;
529
552
}
530
- } finally {
531
- // Only need to close the reader, beginRealtimeHttpStream will disconnect
532
- // the connection
533
- if ( this . reader ) {
534
- void this . reader . cancel ( ) ;
535
- this . reader = undefined ;
536
- }
537
553
}
538
554
}
539
555
@@ -680,6 +696,13 @@ export class RealtimeHandler {
680
696
}
681
697
}
682
698
699
+ /**
700
+ * Handles changes to the application's visibility state, managing the real-time connection.
701
+ *
702
+ * When the application is moved to the background, this method closes the existing
703
+ * real-time connection to save resources. When the application returns to the
704
+ * foreground, it attempts to re-establish the connection.
705
+ */
683
706
private async onVisibilityChange ( visible : unknown ) : Promise < void > {
684
707
this . isInBackground = ! visible ;
685
708
if ( ! visible ) {
0 commit comments