Reputation: 4482
Hey do I need to remove this listener at some point, or does it get removed on its own? I have this called in a fragment within my activity, and users can go to another view without this one being destroyed. Therefore not sure if I am somehow suppose to remove this in an onDestroy
, onPause
call? I do not see a way to remove it since it is a DatabaseReference
Here is the code:
private DatabaseReference mDatabase;
mDatabase.child("projects").orderByChild("viewCount").limitToLast(15).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Upvotes: 2
Views: 10433
Reputation: 892
If you used a ValueEventListener with a child, you must:
ValueEventListener listener;
onCreate(....){
listener = mDatabase.child("projects").addChildEventListener(new ChildEventListener() { ...... }
}
And remove listener:
mDatabase.child("projects").removeEventListener(listener);
The most important thing in this RemoveEventListener is the child () function.
Upvotes: 0
Reputation: 361
private DatabaseReference dbRef;
ValueEventListener mSendEventListner;
dbRef = FirebaseDatabase.getInstance().getReference().child("users").child(phone);
ValueEventListener valueEventListener = new ValueEventListener()
{
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
//
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
//
}
};
dbRef.addValueEventListener(valueEventListener);
mSendEventListner = valueEventListener;
//REMOVE VALUE EVENTLISTNER...
@Override
protected void onDestroy()
{
super.onDestroy();
if (mSendEventListner != null) {
dbRef.removeEventListener(mSendEventListner);
}
}
Upvotes: 0
Reputation: 1653
If you use Query
to add addValueEventListener
. Then you should remove the listener using Query
instance not DatabaseReference
instance.
In question with DatabaseReference
the developer was using orderByChild
which is of type Query
So to remove the listener we need to get reference to Query instance and then use removeEventListener
.
Here is my example of removing the listener:
ValueEventListener carChangesListener;
Query ownerId_Query;
Then
DatabaseReference bikeRef = FirebaseDatabase.getInstance().getReference().child("Cars");
ownerId_Query = bikeRef.orderByChild("ownerId").equalTo(FirebaseAuth.getInstance().getCurrentUser().getUid());
carChangesListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
/*NOTE: handle cars response here*/
}else{
Toast.makeText(getActivity(), "No car found for this user.",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(HOME_TAG, "Failed to read value.", databaseError.toException());
Toast.makeText(getActivity(), "Error!" + databaseError.toException().getMessage(),
Toast.LENGTH_LONG).show();
}
};
ownerId_Query.addValueEventListener(bikeChangesListener);
Now to remove the carChangesListener
I will do following:
ownerId_Query.removeEventListener(carChangesListener);
Upvotes: 1
Reputation: 2197
As Frank says, you need to remove the listener from the exact DatabaseReference, not just the root DatabaseReference as I was doing.
To simplify this, I created a small class below:
public class FirebaseListenerRef {
private ValueEventListener listener;
private DatabaseReference ref;
public FirebaseListenerRef(DatabaseReference ref, ValueEventListener listener) {
this.listener = listener;
this.ref = ref;
// Start listening on this ref.
ref.addValueEventListener(listener);
}
public void detach() {
ref.removeEventListener(listener);
}
}
To use this, just create and detach it in paired lifecycle events, e.g.
private FirebaseListenerRef myFirebaseListenerRef;
public void onAttach(Content context) {
super.onAttach(context);
myFirebaseListenerRef = new FirebaseListenerRef(
FirebaseDatabase.getInstance().getReference().child("path-to-listen-on",
new ValueEventListener() {
... implement the listener logic
}
);
}
public void onDetach() {
super.onDetach();
if ( myFirebaseListenerRef != null ) {
// Detach our listener from its reference
myFirebaseListenerRef.detach();
myFirebaseListenerRef == null;
}
}
Upvotes: 2
Reputation: 599601
As the answer superman links to show: you indeed will need to remove the listener in the opposite lifecycle event.
To remove a listener, you need to keep the handle that is returned when you call addChildListener()
:
Query query = mDatabase.child("projects").orderByChild("viewCount").limitToLast(15);
ChildEventListener listener = query.addChildEventListener(new ChildEventListener() { ...
And then pass it to removeEventListener()
:
query.removeChildEventListener(listener);
You can see that I explicitly use a Query
here, since that is what you actually attach your listener to. But if you have a plain DatabaseReference
the same methods are available, since DatabaseReference
inherits from Query
.
Upvotes: 8
Reputation: 6114
Firebase objects are lightweight references to locations in your Firebase Database. There is no need (nor ability) to manage their life-cycle. So, you can just let the Java garbage collector take care of them.
However, once you start attaching listeners (e.g. addValueEventListener()
) you should detach them in the corresponding life-cycle event with removeEventListener()
. Also see Firebase adding listeners in adapters in Android and How stop Listening to firebase location in android.
Upvotes: 4