Karol Kulbaka
Karol Kulbaka

Reputation: 1274

Firebase Realtime database single value listener triggering many times

I'm trying to receive data from database in other value listener.

class MyFragment : Fragment() {

private lateinit var reference: DatabaseReference

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    reference = FirebaseDatabase.getInstance().reference.child("FIRST_ROOT")
            .child("FIRST_CHILD")
            .child("CHILD_1")
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    reference.addValueEventListener(object : EventListener() {
        override fun onDataChange(p0: DataSnapshot?) {
            val childOfSecondRoot= p0?.value
            FirebaseDatabase.getInstance().reference.child("SECOND_ROOT")
                      .child(childOfSecondRoot).addListenerForSingleValueEvent(object : EventListener() {
                          override fun onDataChange(p0: DataSnapshot?) {
                             doingMyJob(p0?.value)
                    }
            })
        }
    })
}

My goal is to run method doingMyJob once per change in observed value in reference.

For some reason event listener added as addListenerForSingleValueEvent is calling method doMyJob one more time for each time reference trigger instead of run it only once per change. First read from reference is OK, but second call doMyJob 2 times, third 3 times and so on. After restart app history starts from beginning. Method doMyJob() don't change any values in database.

For now I know that parent listener is called incrementaly for each single change in observed value.

Database structure:

|MAIN_ROOT |\FIRST_ROOT | \FIRST_CHILD | |DATA_TO_RECEIVED //reference field - parent listener for many events |\SECOND_ROOT | \DATA_TO_RECEIVED // root name received in nested listener-as single value | |CHILD_1 | |CHILD_2 | |CHILD_3

Am I doing something wrong? Is there a possibility to run listener from listener avoiding incremental call of nested listener?

PS: Sorry for ugly code. I was trying to simplyfy problem as much as it was possible.

Upvotes: 3

Views: 3084

Answers (2)

Karol Kulbaka
Karol Kulbaka

Reputation: 1274

Funny thing. Method doMyJob after show dialog launch new fragment (sorry for missed it in my question) and after I close it fragment which add listener in onActivityCreated is relaunched so... val reference is assigned again and another listerer is added.

I just love this kind of bugs. Thanks everybody for help.

Upvotes: 1

Levi Moreira
Levi Moreira

Reputation: 12005

you're using a singleEventListener in your second query, but in your first you're still using a normal event listener that won't go away automatically. So that might be the reason why your code gets called multiple times. So the problem is not that you're single event listener is being called multiple times, but the one above might be and everytime it creates a new single event listener which in turn call your method multiple times.

reference.addValueEventListener(object : EventListener() { //ordinary event listener will be kept running 
        override fun onDataChange(p0: DataSnapshot?) {
            val childOfSecondRoot= p0?.value
            FirebaseDatabase.getInstance().reference.child("SECOND_ROOT")
                      .child(childOfSecondRoot).addListenerForSingleValueEvent(object : EventListener() {
                          override fun onDataChange(p0: DataSnapshot?) {
                             doingMyJob(p0?.value)
                    }
            })
        }
    })

Upvotes: 2

Related Questions