multithreadingkotlinandroid-jetpack-composekotlin-coroutinessuspend

Kotlin compose how to know when suspend function is finished?


This is the complete flow:

this is in the user profile:

.clickable {
         loginViewModel.onLogout()
         isLogin= false
   }

isLogin should be assign to false only when doLogout is finished How can I run another function or code only when this function is done? Can I know when the function is finished?

this is from ViewModel():

fun onLogout() {
        viewModelScope.launch(Dispatchers.IO) {
            withContext(Dispatchers.Main){
                loginStatus = "out"
                getUserType = null
            }
            FirebaseMessaging.getInstance().token.addOnCompleteListener {
                val token = it.result
                viewModelScope.launch(Dispatchers.IO) {
                    try {
                        repo.doLogout(token)
                    }catch (exp: Exception){
                        println("FCM token error")
                    }
                }
            }
        }
    }

This is from the repository:

suspend fun doLogout(token: String) {
        val userId = appService.currentUser!!.id
            realm.write {
                var user = query<UserInfo>("_id = $0", userId).first().find()
                if (user != null) {
                    user = findLatest(user)!!.also {
                        it.FCMToken.remove(token)
                    }
                    copyToRealm(user)
                }
        }
        withContext(Dispatchers.Default) {
            realm.syncSession.uploadAllLocalChanges()
            appService.currentUser?.logOut()
        }
    }

Solution

  • I found the solution that works without errors.

    This is my onLogout in LoginlView:

    suspend fun onLogout(token: String, onCompletion: (Boolean) -> Unit) {
        viewModelScope.launch {
            loadingLogout = true
            withContext(Dispatchers.IO) {
                try {
                    repo.doLogout(token)
                    onCompletion(true)
                } catch (exp: Exception) {
                    println("FCM token error")
                    onCompletion(false)
                }
                withContext(Dispatchers.Main) {
                    loginStatus = "out"
                    getUserType = null
                }
            }
            repo = RealmRepo()
            loadingLogout = false
        }
    }
    

    I use onCompletion to check when the logout is done

    Since this function is suspended, I call (from clickable()) a coroutine like this:

    coroutineScope.launch {
       loginViewModel.onLogout(token!!) { logoutSuccessful ->
           if (logoutSuccessful) {
             context.getSharedPreferences("sharedPreferences", Context.MODE_PRIVATE)
        .edit().apply {
         putBoolean("isLoggedIn", false)
         apply()
                  }
           }
        }
    }