How can we set running order in setOnClickListener?

I have a favorite button, "check if favorite" function and checkRef variable. I am taking the values from Firebase for view pager adapter. I want to check these if i add this to my favorite or not.

This is my favorite button’s setOnClickListener:

buttonLike.setOnClickListener()
            {
                checkFavorite() //
                if(firebaseAuth.currentUser == null)
                {
                    Toast.makeText(this@MainActivity,"pls login", Toast.LENGTH_SHORT).show()
                }
                else
                {
                    if (!checkRef)
                    {
                        removeFromFavorite()
                    }
                    else
                    {
                        addToFavorite()
                    }
                }
            }

And this is my checking function. This function changes the value of the checkRef.

private fun checkFavorite(){
        val checkId = binding.viewPager.currentItem.toString()
        val urlRef = userRef.child(firebaseAuth.uid!!).child("Favorites")
        urlRef.addListenerForSingleValueEvent(object :ValueEventListener{
            override fun onCancelled(error: DatabaseError) {
                print(error.message)
            }
            override fun onDataChange(snapshot: DataSnapshot) {
                if(snapshot.child(checkId).value == null)
                {
                    checkRef = true
                }
                else
                {
                    checkRef = false
                }
            }
        }
        )
    }

When I click the buttonLike button, it is not reading the checkFavorite function although at the top. It is continuing and checking the if-else blocks. After that, it reading checkFavorite function but I have to run checkFavorite() before if-else blocks because checkRef variable is checking in checkFavorite()

I added the Log’s in if-else blocks and i saw that the function is doing if-else block before the top function.

>Solution :

the problem is that urlRef.addListenerForSingleValueEvent invoke a new thread, so the application continue his work exiting the function checkFavorite before to set the variable checkRef .

you can solve in this way:

you need a callback similar to something like:

interface check_favorite_callback
{
   void onEnd();
}

click listener:

buttonLike.setOnClickListener()
        {
            checkFavorite(new check_favorite_callback(){
               void onEnd(){
                  if(firebaseAuth.currentUser == null)
            {
                Toast.makeText(this@MainActivity,"pls login", Toast.LENGTH_SHORT).show()
            }
            else
            {
                if (!checkRef)
                {
                    removeFromFavorite()
                }
                else
                {
                    addToFavorite()
                }
            }
               }
            }) 
        }

function checkFavorite:

private fun checkFavorite(check_favorite_callback callback){
    val checkId = binding.viewPager.currentItem.toString()
    val urlRef = userRef.child(firebaseAuth.uid!!).child("Favorites")
    urlRef.addListenerForSingleValueEvent(object :ValueEventListener{
        override fun onCancelled(error: DatabaseError) {
            print(error.message)
            callback.onEnd();
        }
        override fun onDataChange(snapshot: DataSnapshot) {
            if(snapshot.child(checkId).value == null)
            {
                checkRef = true
            }
            else
            {
                checkRef = false
            }
            callback.onEnd();
        }
    }
    )
}

i write code directly in stackoverflow, so sintactically could be not perfect, try to understand the logic.

Leave a Reply