Reputation: 1348
I have an activity where a User is made to log in. Once the User logs in, the User detail is uploaded to the Firebase which is observed using the LiveData
in the activity.
The problem is even though the data is successfully uploaded, the LiveData is showing that an error occurred.
Activity
class LoginActivity : AppCompatActivity() {
private val RC_SIGN_IN = 123
private val viewModel by viewModel<LoginViewModel>() // Lazy inject ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
loginUser()
observeLoginLiveData()
}
private fun observeLoginLiveData() {
viewModel.onAuthenticationSuccessful().observe(this, Observer { result ->
when (result) {
is Result.Loading -> {
}
is Result.Success<*> -> {
startActivity(Intent(this, MainActivity::class.java))
finish()
}
is Result.Error -> {
clLogin.showSnackbar(R.string.error_login) {}
Timber.e(result.errorMessage)
}
}
})
}
}
ViewModel
class LoginViewModel(val repo: LoginRepository) : ViewModel() {
private val _loginLiveData = MutableLiveData<Result>()
private val loginLiveData: LiveData<Result>
get() = _loginLiveData
fun onAuthenticationSuccessful(): LiveData<Result> {
_loginLiveData.value = Result.Loading
viewModelScope.launch {
_loginLiveData.value = repo.uploadUserDetails()
}
return loginLiveData
}
}
Repository
class LoginRepository {
suspend fun uploadUserDetails(): Result {
val response = withContext(Dispatchers.IO) {
val currentUser = FirebaseUtils.getCurrentUser()
val user = User(currentUser?.displayName, currentUser?.email, currentUser?.photoUrl.toString())
FirebaseFirestore.getInstance()
.collection(FirebaseReferences.COLLECTION_USERS)
.add(user)
}
return if (response.isSuccessful) {
Result.Success("true")
} else {
Result.Error("Error uploading user data")
}
}
}
I have also tried using response.isComplete
but it also returns false everytime.
I don't know what I am missing here. Any help will be appreciated. Thanks.
Upvotes: 0
Views: 170
Reputation: 1348
As suggested in the comment, I changed the code to wait for the result as shown below and now I am getting the proper response:
Changed ViewModel
class LoginViewModel(val repo: LoginRepository) : ViewModel() {
private val _loginLiveData = MutableLiveData<Result>()
private val loginLiveData: LiveData<Result>
get() = _loginLiveData
fun onAuthenticationSuccessful(): LiveData<Result> {
_loginLiveData.value = Result.Loading
viewModelScope.launch {
repo.uploadUserDetails().addOnCompleteListener {
if (it.isSuccessful) {
_loginLiveData.value = Result.Success("true")
} else {
_loginLiveData.value = Result.Error("Error uploading user data")
}
}
}
return loginLiveData
}
}
Changed Repository
class LoginRepository {
suspend fun uploadUserDetails(): Task<DocumentReference> = withContext(Dispatchers.IO) {
val currentUser = FirebaseUtils.getCurrentUser()
val user = User(currentUser?.displayName, currentUser?.email, currentUser?.photoUrl.toString())
FirebaseFirestore.getInstance()
.collection(FirebaseReferences.COLLECTION_USERS)
.add(user)
}
}
Upvotes: 1