Home > front end >  Managing Data With Coroutines
Managing Data With Coroutines

Time:08-26

In my android project I have tried to implement a shared View Model which does all the reading and writing data. I do this by using Mutable Live Data and my activity calls an update function within the View Model to update the Live Data. However I can't figure out how to get the data after it has been accessed. It seems that I am trying to update my UI before the data gets accessed. I have looked up this problem and it seems the solution has something to do with coroutines. I have not been successful implementing coroutines and I always get a null value for my data.

ViewModel :


    private val firebaseDatabase: DatabaseReference = FirebaseDatabase.getInstance().reference
    private val fAuth = FirebaseAuth.getInstance()
    private val user: FirebaseUser = fAuth.currentUser!!

    private var _saveLocation: MutableLiveData<LocationEvent> = MutableLiveData<LocationEvent>()
    val saveLocation: LiveData<LocationEvent> get() = _saveLocation
fun loadData() {
  
           firebaseDatabase.child("User").child(user.uid).child("SaveLocation").get()
                .addOnSuccessListener {
                    _saveLocation.value = LocationEvent(
                        it.child("title").getValue<String>()!!,
                        it.child("organizer").getValue<String>()!!,
                        LatLng(
                            it.child("locationLatLng").child("latitude").value as Double,
                            it.child("locationLatLng").child("longitude").value as Double
                        ),
                        it.child("address").getValue<String>()!!,
                        it.child("description").value as String,
                        it.child("allDay").value as Boolean,
                        it.child("sdate").getValue<Calendar>()!!,
                        it.child("edate").getValue<Calendar>()!!,
                        it.child("notifications").getValue<MutableList<Int>>()!!,
                        user.uid
                    )

                }.addOnFailureListener {}

       

    }

Activity function :

private fun loadSaveData() {
        dataViewModel.loadData()

        //using log statement just to see if any value
        //Always get null

        Log.d("MainFragment", "${dataViewModel.saveLocation.value}")
}

I did not include any attempt at coroutines above.

Question

  1. How can I use coroutines to fix this problem?
  2. If not coroutines than what?
  3. (Side Question) : Why does casting to type Calendar cause a crash?

Any help whether its a solution or pointing me to a solution would be much appreciated.

CodePudding user response:

Whenever you use code with names like "add listener" or "set listener" or ones with words like "fetch" or "async" in the name and take lambda parameters, you are calling an asynchronous function. This means the function returns before it finishes (and usually before it even starts) doing what you requested it to.

The purpose of the listener/callback/lambda function you pass to it is to do something sometime in the future, whenever the work eventually is completed. It could only be a few milliseconds in the future, but it absolutely will not happen until after your other code under the function call is complete.

In this case, your get() call to Firebase is synchronous, and you are adding a listener to it to tell it what to do with the results, when they eventually arrive. Then your flow of code continues on synchronously. Back in your loadSaveData() function, you are checking for the results, but the request and your listener have not been completed yet.

You don't need coroutines to get around this. Coroutines are a convenient syntax for dealing with code that normally uses callbacks, but regardless of whether you use coroutines, you need to understand what is going on. IO operations like what you're using cannot be done on the main thread, which is why they are done synchronously.

There's a lot more info about this in this StackOverflow question.

  • Related