How to get Data from Firebase using Kotlin?

29
August 01, 2019, at 4:30 PM

I'm trying to get an information ('firstDate') saved in firebase using this code:

if(currentUser != null){
    val ref = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().currentUser!!.uid)
    val menuListener = object : ValueEventListener {
        override fun onCancelled(databaseError: DatabaseError) {
            // handle error
        }
        @SuppressLint("SetTextI18n", "LongLogTag")
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            user = dataSnapshot.getValue(User::class.java)
            Log.i("************************* before Assignement", myFirstDay)
            myFirstDay = user?.firstDate
            Log.i("************************* after Assignement", myFirstDay)
        }
    }
    ref.addValueEventListener(menuListener)
}
getFirstDayReg()
Log.i("************************* myFirstDayReg", myFirstDay)

The problem: anything before ref.addValueEventListener(menuListener) returns the correct answer but this one :

    Log.i("************************* myFirstDayReg", myFirstDay)

It does not giving me anything (no return / nothing at all )

Please help to get the value user?.firstDate and assigned in myFirstDay because I need to use it later on my code.

According to Mr. Alex answer i made this code but i still have the same problem nothing changed

interface MyCallback {
    fun onCallback(value: String)
}
fun readData(myCallback: MyCallback){
        if(currentUser != null){
            val ref = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().currentUser!!.uid)
        val menuListener = object : ValueEventListener {
            override fun onCancelled(databaseError: DatabaseError) {
                // handle error
            }
            @SuppressLint("SetTextI18n", "LongLogTag")
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                user = dataSnapshot.getValue(User::class.java)
                Log.i("************************* before Assignement", user?.firstDate!!)
                myFirstDay = user?.firstDate!!
                myCallback.onCallback(user?.firstDate!!)
            }
        }
        ref.addListenerForSingleValueEvent(menuListener)
    }
}
readData(object: MyCallback {
    override fun onCallback(value: String) {
        Log.d("TAGTAGTAGTAGTAGTAGTAG", user?.firstDate)
    }
})
Answer 1

The following line of code does not giving your anything because it is placed outside the callback:

Log.i("************************* myFirstDayReg", myFirstDay)

By the time this line is called, the data isn't finished loaded from the database. Remember, Firebase APIs are asynchronous, meaning that onDataChange() method returns immediately after it's invoked, but the result that you get from the database comes some time later. There are no guarantees about how long it will take. So it may take from a few hundred milliseconds to a few seconds before the data is available. Because that method returns immediately, the value of your myFirstDay variable you're trying to use it outside the onDataChange() method, will not have been populated from the callback yet.

Basically, you're trying to use the value of myFirstDay synchronously from an API that's asynchronous. That's not a good idea. You should handle the APIs asynchronously as intended.

A quick solve for this problem would be to use myFirstDay only inside the callback, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

READ ALSO
Can I temporarily stop to open other apps through my app for specific time?

Can I temporarily stop to open other apps through my app for specific time?

i am developing phone addiction Android app in this app i need a functionality don't open particular app for specific time

52
How to show a customized Popup window near the touch location, like what we have when we use ContextMenu?

How to show a customized Popup window near the touch location, like what we have when we use ContextMenu?

Seeing that it's not officially possible to have a context menu which has a customized view or even icons for its rows (here), I decided to create my own solution (of custom view that acts like it)

22
Android Geofencing Examples

Android Geofencing Examples

Are there any geofencing application examples that:

20