1

First of all I'm new to Firebase Database. What I need to do is I have some calls to do, to fetch some data. I'm able to get those data like this.

 val query = mDatabaseReference
            ?.child("Node1")
            ?.child("Node1_id")

    val hostList = mutableListOf<Class>()

    query?.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onCancelled(databaseError: DatabaseError) {}

        override fun onDataChange(dataSnapshot: DataSnapshot) {

            dataSnapshot.children.forEach({ node1Details ->
                val hostDetailsQuery = mDatabaseReference
                        ?.child("Node1Details")
                        ?.child(node1Details.key)


                hostDetailsQuery?.addListenerForSingleValueEvent(object : ValueEventListener {
                    override fun onCancelled(databaseError: DatabaseError) {

                    }

                    override fun onDataChange(dataSnapshot: DataSnapshot) {

                        val host = dataSnapshot.getValue(MyClass::class.java)

                        val ratingQuery = mDatabaseReference
                                ?.child("Rating")
                                ?.child(node1Details.key)
                                ?.child(id)

                        ratingQuery?.addListenerForSingleValueEvent(object : ValueEventListener {
                            override fun onCancelled(databaseError: DatabaseError) {

                            }

                            override fun onDataChange(dataSnapshot: DataSnapshot) {

                                host?.myRating = if (dataSnapshot.value == null) 0 else (dataSnapshot.value as Long).toInt()

                                hostList.add(host!!)

                            }
                        })
                    }
                })
            })
        }
    })

What I don't know how to solve is waiting until all calls are finished to call a specific method.

Hope I was clear, and hope someone can help me out.

Thanks in advance.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
ArbenMaloku
  • 548
  • 4
  • 15
  • So basically what is the problem, you are trying ti use `hostList` outside the `onDataChange` function and is empty? – Alex Mamo Apr 24 '18 at 16:10
  • Yes, this is the main problem. I cannot use this list outside the `onDataChanged` since I don't know if the data are fetched completely or not. – ArbenMaloku Apr 25 '18 at 06:12

1 Answers1

0

This is happening because the onDataChange() functions has an asynchronous behaviour which means that is called even before you are trying to add those objects to the hostList. With other words, by the time you are trying to use the list outside onDataChange() function, the data hasn't finished loading yet from the database and that's why the list is always empty.

You can solve this problem in two ways. One way would be to declare and use the list only inside the onDataChange() function like this:

ratingQuery?.addListenerForSingleValueEvent(object : ValueEventListener {
    override fun onCancelled(databaseError: DatabaseError) {}

    override fun onDataChange(dataSnapshot: DataSnapshot) {
        val hostList = mutableListOf<Class>()
        host?.myRating = if (dataSnapshot.value == null) 0 else (dataSnapshot.value as Long).toInt()
        hostList.add(host!!)
        //Do what you want with your list
    }
})

The second approach would be to create your own callback to wait for Firebase to return you the data and for that I recommend you see the last part of my anwser from this post and also take a look at this video. The answer is written in Java but is simmilar for Kotlin.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193