簡體   English   中英

使用 FirebaseAuth 時使用相同的數據多次調用 LiveData onChanged

[英]LiveData onChanged called multiple times with the same data when using FirebaseAuth

我有一個登錄活動,它使用 email 和密碼實現 Firebase 身份驗證。 它所做的是將用戶輸入的 email 和密碼發送到 FirebaseAuth function 並通過 LiveData 檢索響應,然后觀察它。

問題是,當登錄失敗或憑證無效時,它應該烤一次消息,但真正發生的是多次烤,可能超過4次(它使烤顯示很長時間)。

登錄活動

    private fun signInWithEmailAndPassword(email: String, password: String){
        val authResult = viewModel.authWithEmailPassword(email, password)
        handleAuthenticationResult(authResult)
    }

    private fun handleAuthenticationResult(authResult: LiveData<Resource<AuthResult>>){
        authResult.observe(this, object : Observer<Resource<AuthResult>>{
            override fun onChanged(it: Resource<AuthResult>?) {
                when(it){
                    is Resource.Loading -> {
                        toggleLoadingIndicator(true)
                    }
                    is Resource.Success -> {
                        toggleLoadingIndicator(false)

                        val isNewUser = it.data.additionalUserInfo?.isNewUser ?: true

                        if(isNewUser) gotoIntroActivity()
                        else gotoMainActivity()
                    }
                    is Resource.Failure -> {
                        toggleLoadingIndicator(false)

                        when(it.throwable){
                            is FirebaseAuthException -> Toast.makeText(this@LoginActivity, getString(R.string.error_credentials_invalid), Toast.LENGTH_SHORT).show()
                            else -> Toast.makeText(this@LoginActivity, getString(R.string.error_login_failed), Toast.LENGTH_SHORT).show()
                        }
                    }
                }
            }
        })
    }

視圖模型

    fun authWithEmailPassword(email: String, password: String): LiveData<Resource<AuthResult>>{
        return AuthRepository.signInWithEmailAndPassword(email, password)
    }

Firebase 身份驗證

    private var authResult: MutableLiveData<Resource<AuthResult>> = MutableLiveData()

    fun signInWithEmailAndPassword(email: String, password: String): LiveData<Resource<AuthResult>>{
        authResult.value = Resource.Loading()

        mAuth.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener{
                    if(it.isSuccessful) authResult.value = Resource.Success(it.result!!)
                    else authResult.value = Resource.Failure(it.exception!!)
                }

        return authResult
    }

資源

sealed class Resource<out T> {
    class Loading<out T> : Resource<T>()
    data class Success<out T>(val data: T) : Resource<T>()
    data class Failure<out T>(val throwable: Throwable) : Resource<T>()
}

為什么會發生這種情況以及如何解決這個問題? 每次觸發Resource.Failure時我應該刪除觀察者嗎?

LiveData 是您只創建和訂閱一次的東西。 在您的情況下,每次獲得身份驗證結果時都會訂閱它,因此會出現多個重復事件。

為了解決這個問題,請執行以下操作:

  1. 在您的視圖模型中,聲明 livedata:

val authResult: MutableLiveData<Resource<AuthResult>> = MutableLiveData()

  1. 在您的 Activity 的 onCreate() 中,訂閱此 liveData:

viewModel.authResult.observe(this, ... [the rest of your code]

  1. 當您獲得身份驗證結果時,只需將其發布到 liveData。 不要重新訂閱直播數據,不要創建新的直播數據。

authResult.postValue(resource)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM