0

I am calling a function that return an array from my firebase realtime database. Since the function need few seconds to be executed, i need to stop my code until the function return the value. i think i have to user coroutines but it is a little bit confusing

Any suggestion?

fun fetchUserInfo(user: User): ArrayList<String>{
    val userId = user.uid
    val userLanguageArray = arrayListOf<String>()
     val userLanguagesReference = FirebaseDatabase.getInstance().getReference("/languages/$userId/")
    userLanguagesReference.addValueEventListener(object: ValueEventListener{
        override fun onDataChange(snapshot: DataSnapshot) {
            userLanguageArray.clear()
            snapshot.children.forEach(){
                val a = it.value.toString()
                userLanguageArray.add(a)
                //Toast.makeText(context,"${userLanguageArray[0]}",Toast.LENGTH_SHORT).show()
            }
        }
        override fun onCancelled(error: DatabaseError) {
        }
    })
     return  userLanguageArray

}

allUsersRef.addValueEventListener(object : ValueEventListener{
    override fun onDataChange(snapshot: DataSnapshot) {
        mMap.clear()
        val latLng = LatLng(mlatitude,mlongitude)
        val markerOptions = MarkerOptions().position(latLng).title(HomeActivity.newUser?.name)
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

        mMarker = mMap.addMarker(markerOptions)

        mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng))
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng,10f))
        User_Id_HashMap.clear()
        User_distance_HashMap.clear()

        snapshot.children.forEach() {
            val user = it.getValue(User::class.java)
            val userLanguage =  fetchUserInfo(user!!)
            Log.d("TAG","$userLanguage[0]")                    
        }    
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
jawad
  • 11
  • 1
  • There's not way to make the code wait, as that'd lead to a bad user experience. Any code that needs the data from the database, needs to be inside `onDataChange`, be called from there, or be otherwise synchronized. – Frank van Puffelen Mar 04 '22 at 18:02
  • Since you're using Kotlin, this [article](https://medium.com/firebase-tips-tricks/how-to-read-data-from-cloud-firestore-using-get-bf03b6ee4953) with the corresponding [repo](https://github.com/alexmamo/CloudFirestore/tree/master) will help for sure. – Alex Mamo Mar 05 '22 at 09:37

1 Answers1

0

You're actually right. This is a case where you would benefit from coroutine implementation.

Stackoverflow Answer on handling firebase Response

You have a few options here

  1. Interface -> make it trigger only when you get the data
  2. Async Task -> use AnyncTask method to understand. Not really recommended because of FireBase Asynchronous Nature
  3. Create a delay artificially (not recommended again)
 Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                {
                    // your code once you get the data
                }
            }
        }, 2000);// 2000 milliseconds = 2seconds
Narendra_Nath
  • 4,578
  • 3
  • 13
  • 31