@@ -42,7 +42,7 @@ class FirestackDBReference {
4242
4343 private String mPath ;
4444 private ReadableArray mModifiers ;
45- private Map mListeners ;
45+ private HashMap < String , Boolean > mListeners = new HashMap < String , Boolean >() ;
4646 private FirestackDatabaseModule mDatabase ;
4747 private ChildEventListener mEventListener ;
4848 private ValueEventListener mValueListener ;
@@ -64,31 +64,33 @@ public void addChildEventListener(final String name, final ReadableArray modifie
6464 mEventListener = new ChildEventListener () {
6565 @ Override
6666 public void onChildAdded (DataSnapshot dataSnapshot , String previousChildName ) {
67- self .handleDatabaseEvent (name , dataSnapshot );
67+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
6868 }
6969
7070 @ Override
7171 public void onChildChanged (DataSnapshot dataSnapshot , String previousChildName ) {
72- self .handleDatabaseEvent (name , dataSnapshot );
72+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
7373 }
7474
7575 @ Override
7676 public void onChildRemoved (DataSnapshot dataSnapshot ) {
77- self .handleDatabaseEvent (name , dataSnapshot );
77+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
7878 }
7979
8080 @ Override
8181 public void onChildMoved (DataSnapshot dataSnapshot , String previousChildName ) {
82- self .handleDatabaseEvent (name , dataSnapshot );
82+ self .handleDatabaseEvent (name , mPath , dataSnapshot );
8383 }
8484
8585 @ Override
8686 public void onCancelled (DatabaseError error ) {
87- self .handleDatabaseError (name , error );
87+ self .handleDatabaseError (name , mPath , error );
8888 }
8989 };
90+
9091 Query ref = this .getDatabaseQueryAtPathAndModifiers (modifiers );
9192 ref .addChildEventListener (mEventListener );
93+ this .setListeningTo (mPath , name );
9294 }
9395
9496 public void addValueEventListener (final String name , final ReadableArray modifiers ) {
@@ -97,19 +99,18 @@ public void addValueEventListener(final String name, final ReadableArray modifie
9799 mValueListener = new ValueEventListener () {
98100 @ Override
99101 public void onDataChange (DataSnapshot dataSnapshot ) {
100- Log .d (TAG , "onDataChange called for " + name );
101- self .handleDatabaseEvent ("value" , dataSnapshot );
102+ self .handleDatabaseEvent ("value" , mPath , dataSnapshot );
102103 }
103104
104105 @ Override
105106 public void onCancelled (DatabaseError error ) {
106- Log .d (TAG , "onDataChange onCancelled called" );
107- self .handleDatabaseError ("value" , error );
107+ self .handleDatabaseError ("value" , mPath , error );
108108 }
109109 };
110110
111111 Query ref = this .getDatabaseQueryAtPathAndModifiers (modifiers );
112112 ref .addValueEventListener (mValueListener );
113+ this .setListeningTo (mPath , "value" );
113114 }
114115
115116 public void addOnceValueEventListener (final ReadableArray modifiers ,
@@ -119,7 +120,7 @@ public void addOnceValueEventListener(final ReadableArray modifiers,
119120 mOnceValueListener = new ValueEventListener () {
120121 @ Override
121122 public void onDataChange (DataSnapshot dataSnapshot ) {
122- WritableMap data = FirestackUtils .dataSnapshotToMap ("value" , dataSnapshot );
123+ WritableMap data = FirestackUtils .dataSnapshotToMap ("value" , mPath , dataSnapshot );
123124 callback .invoke (null , data );
124125 }
125126
@@ -137,7 +138,27 @@ public void onCancelled(DatabaseError error) {
137138 ref .addListenerForSingleValueEvent (mOnceValueListener );
138139 }
139140
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+
140160 public void cleanup () {
161+ Log .d (TAG , "cleaning up database reference " + this );
141162 this .removeChildEventListener ();
142163 this .removeValueEventListener ();
143164 }
@@ -146,6 +167,10 @@ public void removeChildEventListener() {
146167 if (mEventListener != null ) {
147168 DatabaseReference ref = this .getDatabaseRef ();
148169 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" );
149174 mEventListener = null ;
150175 }
151176 }
@@ -154,29 +179,30 @@ public void removeValueEventListener() {
154179 if (mValueListener != null ) {
155180 DatabaseReference ref = this .getDatabaseRef ();
156181 ref .removeEventListener (mValueListener );
182+ this .notListeningTo (mPath , "value" );
157183 mValueListener = null ;
158184 }
159185 }
160186
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 );
164189 WritableMap evt = Arguments .createMap ();
165190 evt .putString ("eventName" , name );
191+ evt .putString ("path" , path );
166192 evt .putMap ("body" , data );
167193
168194 FirestackUtils .sendEvent (mReactContext , "database_event" , evt );
169195 }
170196
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 ) {
173198 WritableMap err = Arguments .createMap ();
174199 err .putInt ("errorCode" , error .getCode ());
175200 err .putString ("errorDetails" , error .getDetails ());
176201 err .putString ("description" , error .getMessage ());
177202
178203 WritableMap evt = Arguments .createMap ();
179204 evt .putString ("eventName" , name );
205+ evt .putString ("path" , path );
180206 evt .putMap ("body" , err );
181207
182208 FirestackUtils .sendEvent (mReactContext , "database_error" , evt );
@@ -196,7 +222,6 @@ private Query getDatabaseQueryAtPathAndModifiers(final ReadableArray modifiers)
196222 while (it .hasNext ()) {
197223 String str = (String ) it .next ();
198224
199- Log .d (TAG , "getReference with modifiers: " + str );
200225 String [] strArr = str .split (":" );
201226 String methStr = strArr [0 ];
202227
@@ -404,21 +429,21 @@ public void on(final String path,
404429 final ReadableArray modifiers ,
405430 final String name ,
406431 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 ();
409435
410436 if (name .equals ("value" )) {
411437 ref .addValueEventListener (name , modifiers );
412438 } else {
413439 ref .addChildEventListener (name , modifiers );
414440 }
415441
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 );
421443 resp .putString ("result" , "success" );
444+ Log .d (TAG , "Added listener " + name + " for " + ref );
445+
446+ resp .putString ("handle" , path );
422447 callback .invoke (null , resp );
423448 }
424449
@@ -428,22 +453,22 @@ public void onOnce(final String path,
428453 final String name ,
429454 final Callback callback ) {
430455 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" );
432457 ref .addOnceValueEventListener (modifiers , callback );
433458 }
434459
435460 @ ReactMethod
436461 public void off (final String path , final String name , final Callback callback ) {
437462 // TODO
438- FirestackDBReference ref = this .getDBHandle (path );
463+ FirestackDBReference ref = this .getDBHandle (path , name );
439464
440465 if (name .equals ("value" )) {
441466 ref .removeValueEventListener ();
442467 } else {
443468 ref .removeChildEventListener ();
444469 }
445470
446- this .removeDBHandle (path );
471+ this .removeDBHandle (path , name );
447472 Log .d (TAG , "Removed listener " + name );
448473 WritableMap resp = Arguments .createMap ();
449474 resp .putString ("handle" , path );
@@ -544,28 +569,36 @@ private void handleCallback(
544569 }
545570 }
546571
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 )) {
549575 ReactContext ctx = getReactApplicationContext ();
550- mDBListeners .put (path , new FirestackDBReference (ctx , path ));
576+ mDBListeners .put (key , new FirestackDBReference (ctx , path ));
551577 }
552578
553- return mDBListeners .get (path );
579+ return mDBListeners .get (key );
554580 }
555581
556582 private void saveDBHandle (final String path ,
583+ final String eventName ,
557584 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 );
560588 }
561589
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 );
565594 r .cleanup ();
566595 }
567596 }
568597
598+ private String keyPath (final String path , final String eventName ) {
599+ return path + "-" + eventName ;
600+ }
601+
569602 // TODO: move to FirestackDBReference?
570603 private DatabaseReference getDatabaseReferenceAtPath (final String path ) {
571604 DatabaseReference mDatabase = FirebaseDatabase .getInstance ().getReference (path );
@@ -583,8 +616,6 @@ private Query getDatabaseQueryAtPathAndModifiers(
583616
584617 while (it .hasNext ()) {
585618 String str = (String ) it .next ();
586-
587- Log .d (TAG , "getReference with modifiers: " + str );
588619 String [] strArr = str .split (":" );
589620 String methStr = strArr [0 ];
590621
@@ -638,8 +669,8 @@ private Query getDatabaseQueryAtPathAndModifiers(
638669 return query ;
639670 }
640671
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 );
643674 }
644675
645676 private <Any > Any castSnapshotValue (DataSnapshot snapshot ) {
0 commit comments