@@ -100,11 +100,24 @@ class Firestore extends JsObjectWrapper<firestore_interop.FirestoreJsImpl> {
100100 firestore_interop.enableIndexedDbPersistence (jsObject).toDart;
101101 }
102102
103- String get _snapshotInSyncWindowsKey =>
104- 'flutterfire-${app .name }_snapshotInSync' ;
103+ // purely for debug mode and tracking listeners to clean up on "hot restart"
104+ final Map <String , int > _snapshotInSyncListeners = {};
105+ String _snapshotInSyncWindowsKey () {
106+ if (kDebugMode) {
107+ final key = 'flutterfire-${app .name }_snapshotInSync' ;
108+ if (_snapshotInSyncListeners.containsKey (key)) {
109+ _snapshotInSyncListeners[key] = _snapshotInSyncListeners[key]! + 1 ;
110+ } else {
111+ _snapshotInSyncListeners[key] = 0 ;
112+ }
113+ return '$key -${_snapshotInSyncListeners [key ]}' ;
114+ }
115+ return 'no-op' ;
116+ }
105117
106118 Stream <void > snapshotsInSync () {
107- unsubscribeWindowsListener (_snapshotInSyncWindowsKey);
119+ final snapshotKey = _snapshotInSyncWindowsKey ();
120+ unsubscribeWindowsListener (snapshotKey);
108121 late StreamController <void > controller;
109122 late JSFunction onSnapshotsInSyncUnsubscribe;
110123 var nextWrapper = ((JSObject ? noValue) {
@@ -115,15 +128,15 @@ class Firestore extends JsObjectWrapper<firestore_interop.FirestoreJsImpl> {
115128 onSnapshotsInSyncUnsubscribe =
116129 firestore_interop.onSnapshotsInSync (jsObject, nextWrapper);
117130 setWindowsListener (
118- _snapshotInSyncWindowsKey ,
131+ snapshotKey ,
119132 onSnapshotsInSyncUnsubscribe,
120133 );
121134 }
122135
123136 void stopListen () {
124137 onSnapshotsInSyncUnsubscribe.callAsFunction ();
125138 controller.close ();
126- removeWindowsListener (_snapshotInSyncWindowsKey );
139+ removeWindowsListener (snapshotKey );
127140 }
128141
129142 controller = StreamController <void >.broadcast (
@@ -373,8 +386,20 @@ class DocumentReference
373386 (result)! as firestore_interop.DocumentSnapshotJsImpl );
374387 }
375388
376- String get _documentSnapshotWindowsKey =>
377- 'flutterfire-${firestore .app .name }_${path }_documentSnapshot' ;
389+ // purely for debug mode and tracking listeners to clean up on "hot restart"
390+ final Map <String , int > _docListeners = {};
391+ String _documentSnapshotWindowsKey () {
392+ if (kDebugMode) {
393+ final key = 'flutterfire-${firestore .app .name }_${path }_documentSnapshot' ;
394+ if (_docListeners.containsKey (key)) {
395+ _docListeners[key] = _docListeners[key]! + 1 ;
396+ } else {
397+ _docListeners[key] = 0 ;
398+ }
399+ return '$key -${_docListeners [key ]}' ;
400+ }
401+ return 'no-op' ;
402+ }
378403
379404 /// Attaches a listener for [DocumentSnapshot] events.
380405 Stream <DocumentSnapshot > onSnapshot ({
@@ -391,7 +416,8 @@ class DocumentReference
391416 StreamController <DocumentSnapshot > _createSnapshotStream ([
392417 firestore_interop.DocumentListenOptions ? options,
393418 ]) {
394- unsubscribeWindowsListener (_documentSnapshotWindowsKey);
419+ final documentKey = _documentSnapshotWindowsKey ();
420+ unsubscribeWindowsListener (documentKey);
395421 late JSFunction onSnapshotUnsubscribe;
396422 // ignore: close_sinks, the controller is returned
397423 late StreamController <DocumentSnapshot > controller;
@@ -408,12 +434,12 @@ class DocumentReference
408434 jsObject as JSObject , options as JSAny , nextWrapper, errorWrapper)
409435 : firestore_interop.onSnapshot (
410436 jsObject as JSObject , nextWrapper, errorWrapper);
411- setWindowsListener (_documentSnapshotWindowsKey , onSnapshotUnsubscribe);
437+ setWindowsListener (documentKey , onSnapshotUnsubscribe);
412438 }
413439
414440 void stopListen () {
415441 onSnapshotUnsubscribe.callAsFunction ();
416- removeWindowsListener (_documentSnapshotWindowsKey );
442+ removeWindowsListener (documentKey );
417443 }
418444
419445 return controller = StreamController <DocumentSnapshot >.broadcast (
@@ -486,8 +512,20 @@ class Query<T extends firestore_interop.QueryJsImpl>
486512 Query limitToLast (num limit) => Query .fromJsObject (firestore_interop.query (
487513 jsObject, firestore_interop.limitToLast (limit.toJS)));
488514
489- String _querySnapshotWindowsKey (hashCode) =>
490- 'flutterfire-${firestore .app .name }_${hashCode }_querySnapshot' ;
515+ // purely for debug mode and tracking listeners to clean up on "hot restart"
516+ final Map <String , int > _snapshotListeners = {};
517+ String _querySnapshotWindowsKey (hashCode) {
518+ if (kDebugMode) {
519+ final key = 'flutterfire-${firestore .app .name }_${hashCode }_querySnapshot' ;
520+ if (_snapshotListeners.containsKey (key)) {
521+ _snapshotListeners[key] = _snapshotListeners[key]! + 1 ;
522+ } else {
523+ _snapshotListeners[key] = 0 ;
524+ }
525+ return '$key -${_snapshotListeners [key ]}' ;
526+ }
527+ return 'no-op' ;
528+ }
491529
492530 Stream <QuerySnapshot > onSnapshot (
493531 {bool includeMetadataChanges = false ,
@@ -505,7 +543,8 @@ class Query<T extends firestore_interop.QueryJsImpl>
505543 firestore_interop.DocumentListenOptions options,
506544 int hashCode,
507545 ) {
508- unsubscribeWindowsListener (_querySnapshotWindowsKey (hashCode));
546+ final snapshotKey = _querySnapshotWindowsKey (hashCode);
547+ unsubscribeWindowsListener (snapshotKey);
509548 late JSFunction onSnapshotUnsubscribe;
510549 // ignore: close_sinks, the controller is returned
511550 late StreamController <QuerySnapshot > controller;
@@ -519,12 +558,14 @@ class Query<T extends firestore_interop.QueryJsImpl>
519558 onSnapshotUnsubscribe = firestore_interop.onSnapshot (
520559 jsObject as JSObject , options as JSObject , nextWrapper, errorWrapper);
521560 setWindowsListener (
522- _querySnapshotWindowsKey (hashCode), onSnapshotUnsubscribe);
561+ snapshotKey,
562+ onSnapshotUnsubscribe,
563+ );
523564 }
524565
525566 void stopListen () {
526567 onSnapshotUnsubscribe.callAsFunction ();
527- removeWindowsListener (_querySnapshotWindowsKey (hashCode) );
568+ removeWindowsListener (snapshotKey );
528569 }
529570
530571 return controller = StreamController <QuerySnapshot >.broadcast (
0 commit comments