3
3
import android .content .Context ;
4
4
import android .util .Log ;
5
5
import java .util .HashMap ;
6
- import java .util .Iterator ;
7
6
import java .util .List ;
8
7
import java .util .ListIterator ;
9
- import java .util .ArrayList ;
10
8
import java .util .Map ;
11
9
import android .net .Uri ;
12
10
13
- import android .support .annotation .NonNull ;
14
- import android .support .annotation .Nullable ;
15
-
16
11
import com .facebook .react .bridge .Arguments ;
17
12
import com .facebook .react .bridge .ReactApplicationContext ;
18
13
import com .facebook .react .bridge .ReactContextBaseJavaModule ;
24
19
import com .facebook .react .bridge .ReadableArray ;
25
20
import com .facebook .react .bridge .ReactContext ;
26
21
27
- import com .google .android .gms .tasks .OnCompleteListener ;
28
- import com .google .android .gms .tasks .OnFailureListener ;
29
- import com .google .android .gms .tasks .Task ;
30
- import com .google .firebase .FirebaseApp ;
31
-
32
22
import com .google .firebase .database .FirebaseDatabase ;
33
23
import com .google .firebase .database .DatabaseReference ;
34
24
import com .google .firebase .database .ChildEventListener ;
@@ -146,6 +136,9 @@ public Boolean isListeningTo(final String path, final String evtName) {
146
136
return mListeners .containsKey (key );
147
137
}
148
138
139
+ /**
140
+ * Note: these path/eventType listeners only get removed when javascript calls .off() and cleanup is run on the entire path
141
+ */
149
142
public void setListeningTo (final String path , final String evtName ) {
150
143
String key = this .pathListeningKey (path , evtName );
151
144
mListeners .put (key , true );
@@ -179,12 +172,16 @@ public void removeChildEventListener() {
179
172
}
180
173
181
174
public void removeValueEventListener () {
175
+ DatabaseReference ref = this .getDatabaseRef ();
182
176
if (mValueListener != null ) {
183
- DatabaseReference ref = this .getDatabaseRef ();
184
177
ref .removeEventListener (mValueListener );
185
178
this .notListeningTo (mPath , "value" );
186
179
mValueListener = null ;
187
180
}
181
+ if (mOnceValueListener != null ) {
182
+ ref .removeEventListener (mOnceValueListener );
183
+ mOnceValueListener = null ;
184
+ }
188
185
}
189
186
190
187
private void handleDatabaseEvent (final String name , final String path , final DataSnapshot dataSnapshot ) {
@@ -435,7 +432,7 @@ public void on(final String path,
435
432
final ReadableArray modifiers ,
436
433
final String name ,
437
434
final Callback callback ) {
438
- FirestackDBReference ref = this .getDBHandle (path , name );
435
+ FirestackDBReference ref = this .getDBHandle (path );
439
436
440
437
WritableMap resp = Arguments .createMap ();
441
438
@@ -445,7 +442,7 @@ public void on(final String path,
445
442
ref .addChildEventListener (name , modifiers );
446
443
}
447
444
448
- this .saveDBHandle (path , name , ref );
445
+ this .saveDBHandle (path , ref );
449
446
resp .putString ("result" , "success" );
450
447
Log .d (TAG , "Added listener " + name + " for " + ref );
451
448
@@ -459,14 +456,20 @@ public void onOnce(final String path,
459
456
final String name ,
460
457
final Callback callback ) {
461
458
Log .d (TAG , "Setting one-time listener on event: " + name + " for path " + path );
462
- FirestackDBReference ref = this .getDBHandle (path , "once" );
459
+ FirestackDBReference ref = this .getDBHandle (path );
463
460
ref .addOnceValueEventListener (modifiers , callback );
464
461
}
465
462
463
+ /**
464
+ * At the time of this writing, off() only gets called when there are no more subscribers to a given path.
465
+ * `mListeners` might therefore be out of sync (though javascript isnt listening for those eventTypes, so
466
+ * it doesn't really matter- just polluting the RN bridge a little more than necessary.
467
+ * off() should therefore clean *everything* up
468
+ */
466
469
@ ReactMethod
467
- public void off (final String path , final String name , final Callback callback ) {
468
- String keyPath = this .keyPath (path , name );
469
- this . removeDBHandle ( keyPath );
470
+ public void off (final String path , @ Deprecated final String name , final Callback callback ) {
471
+ this .removeDBHandle (path );
472
+ Log . d ( TAG , "Removed listener " + path );
470
473
WritableMap resp = Arguments .createMap ();
471
474
resp .putString ("handle" , path );
472
475
resp .putString ("result" , "success" );
@@ -566,27 +569,24 @@ private void handleCallback(
566
569
}
567
570
}
568
571
569
- private FirestackDBReference getDBHandle (final String path , final String eventName ) {
570
- String keyPath = this .keyPath (path , eventName );
571
- if (!mDBListeners .containsKey (keyPath )) {
572
+ private FirestackDBReference getDBHandle (final String path ) {
573
+ if (!mDBListeners .containsKey (path )) {
572
574
ReactContext ctx = getReactApplicationContext ();
573
- mDBListeners .put (keyPath , new FirestackDBReference (ctx , path ));
575
+ mDBListeners .put (path , new FirestackDBReference (ctx , path ));
574
576
}
575
577
576
- return mDBListeners .get (keyPath );
578
+ return mDBListeners .get (path );
577
579
}
578
580
579
- private void saveDBHandle (final String path ,
580
- final String eventName ,
581
- final FirestackDBReference dbRef ) {
582
- String keyPath = this .keyPath (path , eventName );
583
- mDBListeners .put (keyPath , dbRef );
581
+ private void saveDBHandle (final String path , final FirestackDBReference dbRef ) {
582
+ mDBListeners .put (path , dbRef );
584
583
}
585
584
586
- private void removeDBHandle (final String keyPath ) {
587
- if (mDBListeners .containsKey (keyPath )) {
588
- FirestackDBReference r = mDBListeners .get (keyPath );
585
+ private void removeDBHandle (final String path ) {
586
+ if (mDBListeners .containsKey (path )) {
587
+ FirestackDBReference r = mDBListeners .get (path );
589
588
r .cleanup ();
589
+ mDBListeners .remove (path );
590
590
}
591
591
}
592
592
0 commit comments