-3

I am trying to remove my ChildEventListener observer when I leave the activity as shown below in my onPause method. Basically my problem is when I leave the activity and return to it my childListener gets incremented by one so depending on how many times i leave the activity and return to it my System.out.println will print to console "onChildAdded" and "onChildRemoved" multiple times and I only want it to be called once. Any help on how to terminate my Listeners when i leave the activity, thank you in advance :)

// Connect to DB
private DatabaseReference mDataBase;
private FirebaseAuth mAuth = FirebaseAuth.getInstance();
String currentUser_UID = mAuth.getCurrentUser().getUid();
ChildEventListener childListener;

@Override
    protected void onCreate(Bundle savedInstanceState) {

    mDataBase = FirebaseDatabase.getInstance().getReference();
    childListener = mDataBase.child("Users").addChildEventListener(new ChildEventListener() {

        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            String savedCardUser = (String) dataSnapshot.child("Card").getValue();
            System.out.println("onChildAdded");
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            System.out.println("onChildRemoved");
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

    @Override
    protected void onPause() {
        super.onPause();

        mDataBase.removeEventListener(childListener);
     }

Edit

If it wasn't the simplest thing :) had to add the child() paths works perfect now. Successfully removes my Listeners

mDataBase.child("Card").removeEventListener(childListener);
A Parham
  • 27
  • 1
  • 7
  • Your question isn't about stopping anything. It's about preventing it from resuming from a previous instance... Why do you need this? – OneCricketeer Nov 03 '17 at 23:10
  • Because when onChildRemoved gets triggered i am removing an element from my array list and since it is being called multiple times it removes more than 1 item from my array list then crashes because the index it is looking to remove doesn't exist:) – A Parham Nov 03 '17 at 23:12
  • There's no Arraylist in the question. Please show a [mcve] of the actual problem – OneCricketeer Nov 03 '17 at 23:13
  • Showing that is irrelevant to my main problem which is figuring out how to remove the ChildEventListener observer :) My array list problem starts from that issue only – A Parham Nov 03 '17 at 23:15
  • If you test out that code you will notice it prints "onChildAdded" and "onChildRemoved" the exact number of time you visit the activity. Visited Once is prints Once visit Twice is prints Twice and so on. – A Parham Nov 03 '17 at 23:17
  • Your Arraylist should be empty when the Activity starts anyway, so I think it is very relevant – OneCricketeer Nov 03 '17 at 23:20
  • I understand where you’re coming from but the main issue is that it prints/is being called more times than it should :/. So with or without the arraylist I need to remove the childListener when I leave the activity :) – A Parham Nov 03 '17 at 23:22
  • I'm sorry, I don't understand. If your database is updated while the Activity is open at all, there is a print event. In other words, a **childAdded** event. When your Activity starts, all children are read all once from the database, and also additionally as new data arrives. This is the nature of the realtime database. – OneCricketeer Nov 04 '17 at 00:32
  • So for example if I open and go back and fourth from the activity 3 times then in that activity i delete a child from my database the onChildRemoved gets triggered 3 times when only one child was removed – A Parham Nov 04 '17 at 00:35
  • When you delete a Card, or a User? – OneCricketeer Nov 04 '17 at 00:38
  • when i delete a card – A Parham Nov 04 '17 at 00:41
  • 1
    Your listener is set on all users. Can multiple users have the same card instance? – OneCricketeer Nov 04 '17 at 00:46
  • You are not understanding the main issue svi.data is understanding tho so I’m going to try his first – A Parham Nov 04 '17 at 00:48
  • I'm understanding fine. And your current code is properly removing the listener when the activity ends. And it will always read the database when the activity starts until you use some `SharedPreference` boolean flag to tell not to add the listener again. – OneCricketeer Nov 04 '17 at 00:50
  • How do I add one of those Boolean flags? – A Parham Nov 04 '17 at 00:52
  • https://developer.android.com/training/basics/data-storage/shared-preferences.html – OneCricketeer Nov 04 '17 at 00:54

1 Answers1

-1

Hello if adding child event listener is not necessary in your case. You could just use a simple single event listener that will fire only once, so once it gets triggered it won't fire again

so do that

on create method would be the best place to do it in your case :

//in on create method do that 

 //this is your database reference
 mDataBase = FirebaseDatabase.getInstance().getReference();

 //add single event listener like that

 mDataBase.addListenerForSingleValueEvent(new ValueEventListener(){

 //in data change method you do the rest of your code
  @Override
  public void onDataChange(DataSnapshot dataSnapshot){

    String savedCardUser = (String) dataSnapshot.child("Card").getValue();
    System.out.println("onChildAdded");

  } 

  //on canceled.......

 });

And this will fire only once (when your activity creates), and you don't have to worry about removing the listener.

EDIT

okay so if the child event listener fires when you return back to your activity this means that you are attaching the listener in (onResume) or (onStart). If this is what you did then this is the problem, because in activities when you return back to them onstart will fire then on resume and so on...but (onCreate) won't so attach the child event listener in (onCreate) and you won't have problem anymore.

so do this:

 //in on create 

  mDataBase = FirebaseDatabase.getInstance().getReference();
  childListener = mDataBase.child("Users").addChildEventListener(new ChildEventListener() {

@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
    String savedCardUser = (String) dataSnapshot.child("Card").getValue();
    System.out.println("onChildAdded");
}

//and in pause keep the same code (remove the child listener)

EDIT 2

okay I got the problem you remove the listener after super is called so do this in on pause

 @Override
protected void onPause() {
    //this should be before super 
    mDataBase.removeEventListener(childListener);
    super.onPause();


 }
Hasan Bou Taam
  • 4,017
  • 2
  • 12
  • 22