简体   繁体   中英

How to replace callbacks in coroutines android

here is my code, I am using it for logging in user with google,

This is my viewModel code

  fun signInWithGoogle(account: GoogleSignInAccount): LiveData<Resource<Any>> {
        val credential = GoogleAuthProvider.getCredential(account.idToken, null)
        return liveData (IO){
            authRepo.firebaseSignInWithGoogle(credential, object : FetchUser {
                override suspend fun onUserDataFetch(user: User) {
                    this@liveData.emit(Resource.success(user))
                }

                override suspend fun onError(error: AppError?) {
                    this@liveData.emit(Resource.error(error, null))
                }

            })
        }
    }

This is my code authRepository where i am logging the user in and checking if user already exits in database or not according to that performing the work

 suspend fun firebaseSignInWithGoogle(googleAuthCredential: AuthCredential, userCallBack: FetchUser) {
        coroutineScope {
            firebaseAuth.signInWithCredential(googleAuthCredential).await()
            createUpdateUser(userCallBack)
        }
    }


 private suspend fun createUpdateUser(userCallBack: FetchUser) {
        val firebaseUser = firebaseAuth.currentUser
        if (firebaseUser != null) {
            userIntegrator.getUserById(firebaseUser.uid, object : OnDataChanged {
                override suspend fun onChanged(any: Any?) {
                    if (any != null && any is User) {
                        any.isNew = false
                        userIntegrator.createUpdateUser(any, userCallBack)
                    } else {
                        val user = User()
                        user.id = firebaseUser.uid
                        user.name = firebaseUser.displayName
                        user.email = firebaseUser.email
                        user.isNew = true
                        userIntegrator.createUpdateUser(
                            user,
                            userCallBack
                        )
                    }
                }
            })
        }
    }

This is my last class where I am updating the user in database

suspend fun createUpdateUser(user: User, userCallBack: FetchUser) {
        if (user.id.isNullOrEmpty()) {
            userCallBack.onError(AppError(StatusCode.UnSuccess, ""))
            return
        }
        val dp = databaseHelper.dataFirestoreReference?.collection(DatabaseHelper.USERS)?.document()
        dp?.apply {
                dp.set(user.toMap()).await().apply {
                   dp.get().await().toObject(User::class.java)?.let {
                       userCallBack.onUserDataFetch(it)
                   }?: kotlin.run {
                       userCallBack.onError(AppError(StatusCode.Exception,"Unable to add user at the moment"))
                   }
               }
        }
    }

Now here whole thing is that, I am using a FetchUser interface which look like this

interface FetchUser {
    suspend fun onUserDataFetch(user: User)
    suspend fun onError(error: AppError?)
}

I just want to get rid of it and looking for something else in coroutines. Also I just wanted to know the best practice here, What should I do with it.

Also I want to make it unit testable

There are 2 ways, if you want to call and get result directly, you could use suspendCoroutine. Otherway, if you want to get stream of data like, loading, result, error,... you could try callbackFlow Exp:

suspend fun yourMethod() = suspendCoroutine { cont -> 
    // do something 
    cont.resume(result)
}

suspend fun yourMethod() = callbackFlow {
   val callbackImpl = object: yourInterace {
       // your implementation
       fun onSuccess() {
          emit(your result)
       }
       fun onFailed() {
          emit(error)
       }
   }
   handleYourcallback(callbackImpl)  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM