@@ -42,7 +42,7 @@ class FirestackDBReference {
42
42
43
43
private String mPath ;
44
44
private ReadableArray mModifiers ;
45
- private Map mListeners ;
45
+ private HashMap < String , Boolean > mListeners = new HashMap < String , Boolean >() ;
46
46
private FirestackDatabaseModule mDatabase ;
47
47
private ChildEventListener mEventListener ;
48
48
private ValueEventListener mValueListener ;
@@ -64,31 +64,33 @@ public void addChildEventListener(final String name, final ReadableArray modifie
64
64
mEventListener = new ChildEventListener () {
65
65
@ Override
66
66
public void onChildAdded (DataSnapshot dataSnapshot , String previousChildName ) {
67
- self .handleDatabaseEvent (name , dataSnapshot );
67
+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
68
68
}
69
69
70
70
@ Override
71
71
public void onChildChanged (DataSnapshot dataSnapshot , String previousChildName ) {
72
- self .handleDatabaseEvent (name , dataSnapshot );
72
+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
73
73
}
74
74
75
75
@ Override
76
76
public void onChildRemoved (DataSnapshot dataSnapshot ) {
77
- self .handleDatabaseEvent (name , dataSnapshot );
77
+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
78
78
}
79
79
80
80
@ Override
81
81
public void onChildMoved (DataSnapshot dataSnapshot , String previousChildName ) {
82
- self .handleDatabaseEvent (name , dataSnapshot );
82
+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
83
83
}
84
84
85
85
@ Override
86
86
public void onCancelled (DatabaseError error ) {
87
- self .handleDatabaseError (name , error );
87
+ self .handleDatabaseError (name , mPath , error );
88
88
}
89
89
};
90
+
90
91
Query ref = this .getDatabaseQueryAtPathAndModifiers (modifiers );
91
92
ref .addChildEventListener (mEventListener );
93
+ this .setListeningTo (mPath , name );
92
94
}
93
95
94
96
public void addValueEventListener (final String name , final ReadableArray modifiers ) {
@@ -97,19 +99,18 @@ public void addValueEventListener(final String name, final ReadableArray modifie
97
99
mValueListener = new ValueEventListener () {
98
100
@ Override
99
101
public void onDataChange (DataSnapshot dataSnapshot ) {
100
- Log .d (TAG , "onDataChange called for " + name );
101
- self .handleDatabaseEvent ("value" , dataSnapshot );
102
+ self .handleDatabaseEvent ("value" , mPath , dataSnapshot );
102
103
}
103
104
104
105
@ Override
105
106
public void onCancelled (DatabaseError error ) {
106
- Log .d (TAG , "onDataChange onCancelled called" );
107
- self .handleDatabaseError ("value" , error );
107
+ self .handleDatabaseError ("value" , mPath , error );
108
108
}
109
109
};
110
110
111
111
Query ref = this .getDatabaseQueryAtPathAndModifiers (modifiers );
112
112
ref .addValueEventListener (mValueListener );
113
+ this .setListeningTo (mPath , "value" );
113
114
}
114
115
115
116
public void addOnceValueEventListener (final ReadableArray modifiers ,
@@ -119,7 +120,7 @@ public void addOnceValueEventListener(final ReadableArray modifiers,
119
120
mOnceValueListener = new ValueEventListener () {
120
121
@ Override
121
122
public void onDataChange (DataSnapshot dataSnapshot ) {
122
- WritableMap data = FirestackUtils .dataSnapshotToMap ("value" , dataSnapshot );
123
+ WritableMap data = FirestackUtils .dataSnapshotToMap ("value" , mPath , dataSnapshot );
123
124
callback .invoke (null , data );
124
125
}
125
126
@@ -137,7 +138,27 @@ public void onCancelled(DatabaseError error) {
137
138
ref .addListenerForSingleValueEvent (mOnceValueListener );
138
139
}
139
140
141
+ public Boolean isListeningTo (final String path , final String evtName ) {
142
+ String key = this .pathListeningKey (path , evtName );
143
+ return mListeners .containsKey (key );
144
+ }
145
+
146
+ public void setListeningTo (final String path , final String evtName ) {
147
+ String key = this .pathListeningKey (path , evtName );
148
+ mListeners .put (key , true );
149
+ }
150
+
151
+ public void notListeningTo (final String path , final String evtName ) {
152
+ String key = this .pathListeningKey (path , evtName );
153
+ mListeners .remove (key );
154
+ }
155
+
156
+ private String pathListeningKey (final String path , final String eventName ) {
157
+ return "listener/" + path + "/" + eventName ;
158
+ }
159
+
140
160
public void cleanup () {
161
+ Log .d (TAG , "cleaning up database reference " + this );
141
162
this .removeChildEventListener ();
142
163
this .removeValueEventListener ();
143
164
}
@@ -146,6 +167,10 @@ public void removeChildEventListener() {
146
167
if (mEventListener != null ) {
147
168
DatabaseReference ref = this .getDatabaseRef ();
148
169
ref .removeEventListener (mEventListener );
170
+ this .notListeningTo (mPath , "child_added" );
171
+ this .notListeningTo (mPath , "child_changed" );
172
+ this .notListeningTo (mPath , "child_removed" );
173
+ this .notListeningTo (mPath , "child_moved" );
149
174
mEventListener = null ;
150
175
}
151
176
}
@@ -154,29 +179,30 @@ public void removeValueEventListener() {
154
179
if (mValueListener != null ) {
155
180
DatabaseReference ref = this .getDatabaseRef ();
156
181
ref .removeEventListener (mValueListener );
182
+ this .notListeningTo (mPath , "value" );
157
183
mValueListener = null ;
158
184
}
159
185
}
160
186
161
- private void handleDatabaseEvent (final String name , final DataSnapshot dataSnapshot ) {
162
- Log .d (TAG , "handleDatabaseEvent called: " + name );
163
- WritableMap data = FirestackUtils .dataSnapshotToMap (name , dataSnapshot );
187
+ private void handleDatabaseEvent (final String name , final String path , final DataSnapshot dataSnapshot ) {
188
+ WritableMap data = FirestackUtils .dataSnapshotToMap (name , path , dataSnapshot );
164
189
WritableMap evt = Arguments .createMap ();
165
190
evt .putString ("eventName" , name );
191
+ evt .putString ("path" , path );
166
192
evt .putMap ("body" , data );
167
193
168
194
FirestackUtils .sendEvent (mReactContext , "database_event" , evt );
169
195
}
170
196
171
- private void handleDatabaseError (final String name , final DatabaseError error ) {
172
- Log .d (TAG , "handleDatabaseError called: " + name );
197
+ private void handleDatabaseError (final String name , final String path , final DatabaseError error ) {
173
198
WritableMap err = Arguments .createMap ();
174
199
err .putInt ("errorCode" , error .getCode ());
175
200
err .putString ("errorDetails" , error .getDetails ());
176
201
err .putString ("description" , error .getMessage ());
177
202
178
203
WritableMap evt = Arguments .createMap ();
179
204
evt .putString ("eventName" , name );
205
+ evt .putString ("path" , path );
180
206
evt .putMap ("body" , err );
181
207
182
208
FirestackUtils .sendEvent (mReactContext , "database_error" , evt );
@@ -196,7 +222,6 @@ private Query getDatabaseQueryAtPathAndModifiers(final ReadableArray modifiers)
196
222
while (it .hasNext ()) {
197
223
String str = (String ) it .next ();
198
224
199
- Log .d (TAG , "getReference with modifiers: " + str );
200
225
String [] strArr = str .split (":" );
201
226
String methStr = strArr [0 ];
202
227
@@ -404,21 +429,21 @@ public void on(final String path,
404
429
final ReadableArray modifiers ,
405
430
final String name ,
406
431
final Callback callback ) {
407
- Log .d (TAG , "Setting a listener on event: " + name + " for path " + path );
408
- FirestackDBReference ref = this .getDBHandle (path );
432
+ FirestackDBReference ref = this .getDBHandle (path , name );
433
+
434
+ WritableMap resp = Arguments .createMap ();
409
435
410
436
if (name .equals ("value" )) {
411
437
ref .addValueEventListener (name , modifiers );
412
438
} else {
413
439
ref .addChildEventListener (name , modifiers );
414
440
}
415
441
416
- this .saveDBHandle (path , ref );
417
-
418
- Log .d (TAG , "Added listener " + name );
419
- WritableMap resp = Arguments .createMap ();
420
- resp .putString ("handle" , path );
442
+ this .saveDBHandle (path , name , ref );
421
443
resp .putString ("result" , "success" );
444
+ Log .d (TAG , "Added listener " + name + " for " + ref );
445
+
446
+ resp .putString ("handle" , path );
422
447
callback .invoke (null , resp );
423
448
}
424
449
@@ -428,22 +453,22 @@ public void onOnce(final String path,
428
453
final String name ,
429
454
final Callback callback ) {
430
455
Log .d (TAG , "Setting one-time listener on event: " + name + " for path " + path );
431
- FirestackDBReference ref = this .getDBHandle (path );
456
+ FirestackDBReference ref = this .getDBHandle (path , "once" );
432
457
ref .addOnceValueEventListener (modifiers , callback );
433
458
}
434
459
435
460
@ ReactMethod
436
461
public void off (final String path , final String name , final Callback callback ) {
437
462
// TODO
438
- FirestackDBReference ref = this .getDBHandle (path );
463
+ FirestackDBReference ref = this .getDBHandle (path , name );
439
464
440
465
if (name .equals ("value" )) {
441
466
ref .removeValueEventListener ();
442
467
} else {
443
468
ref .removeChildEventListener ();
444
469
}
445
470
446
- this .removeDBHandle (path );
471
+ this .removeDBHandle (path , name );
447
472
Log .d (TAG , "Removed listener " + name );
448
473
WritableMap resp = Arguments .createMap ();
449
474
resp .putString ("handle" , path );
@@ -544,28 +569,36 @@ private void handleCallback(
544
569
}
545
570
}
546
571
547
- private FirestackDBReference getDBHandle (final String path ) {
548
- if (!mDBListeners .containsKey (path )) {
572
+ private FirestackDBReference getDBHandle (final String path , final String eventName ) {
573
+ String key = this .keyPath (path , eventName );
574
+ if (!mDBListeners .containsKey (key )) {
549
575
ReactContext ctx = getReactApplicationContext ();
550
- mDBListeners .put (path , new FirestackDBReference (ctx , path ));
576
+ mDBListeners .put (key , new FirestackDBReference (ctx , path ));
551
577
}
552
578
553
- return mDBListeners .get (path );
579
+ return mDBListeners .get (key );
554
580
}
555
581
556
582
private void saveDBHandle (final String path ,
583
+ final String eventName ,
557
584
final FirestackDBReference dbRef ) {
558
- this .removeDBHandle (path );
559
- mDBListeners .put (path , dbRef );
585
+ String key = this .keyPath (path , eventName );
586
+ this .removeDBHandle (key , eventName );
587
+ mDBListeners .put (key , dbRef );
560
588
}
561
589
562
- private void removeDBHandle (final String path ) {
563
- if (mDBListeners .containsKey (path )) {
564
- FirestackDBReference r = mDBListeners .get (path );
590
+ private void removeDBHandle (final String path , final String eventName ) {
591
+ String key = this .keyPath (path , eventName );
592
+ if (mDBListeners .containsKey (key )) {
593
+ FirestackDBReference r = mDBListeners .get (key );
565
594
r .cleanup ();
566
595
}
567
596
}
568
597
598
+ private String keyPath (final String path , final String eventName ) {
599
+ return path + "-" + eventName ;
600
+ }
601
+
569
602
// TODO: move to FirestackDBReference?
570
603
private DatabaseReference getDatabaseReferenceAtPath (final String path ) {
571
604
DatabaseReference mDatabase = FirebaseDatabase .getInstance ().getReference (path );
@@ -583,8 +616,6 @@ private Query getDatabaseQueryAtPathAndModifiers(
583
616
584
617
while (it .hasNext ()) {
585
618
String str = (String ) it .next ();
586
-
587
- Log .d (TAG , "getReference with modifiers: " + str );
588
619
String [] strArr = str .split (":" );
589
620
String methStr = strArr [0 ];
590
621
@@ -638,8 +669,8 @@ private Query getDatabaseQueryAtPathAndModifiers(
638
669
return query ;
639
670
}
640
671
641
- private WritableMap dataSnapshotToMap (String name , DataSnapshot dataSnapshot ) {
642
- return FirestackUtils .dataSnapshotToMap (name , dataSnapshot );
672
+ private WritableMap dataSnapshotToMap (String name , String path , DataSnapshot dataSnapshot ) {
673
+ return FirestackUtils .dataSnapshotToMap (name , path , dataSnapshot );
643
674
}
644
675
645
676
private <Any > Any castSnapshotValue (DataSnapshot snapshot ) {
0 commit comments