首页 > 解决方案 > 如何处理视图模型内服务类中触发的事件?架构组件、Kotlin、Firebase)

问题描述

我正在寻找对onComplete(), onFailure()视图模型中的 , ... 等事件做出反应的方法。

例如:

我创建了一个名为 EmailSignInService 的类,它OnCompleteListener在用户登录的情况下调用 from firebase 实例。我想在视图模型中处理此事件以更新 UI。

电子邮件登录服务

    fun signInUser(email: String, password: String) {
    auth.signInWithEmailAndPassword(email, password).
        addOnCompleteListener(OnCompleteListener<AuthResult> { task -> {
        if(task.isSuccessful) {
            val currentUser = auth.currentUser;
            // inform somehow viewmodel to change UI state later
        } //...
    } });
}

登录视图模型

class LoginViewModel : ViewModel() {
var userName: String? = null; //...
var userPassword: String? = null; //...

// Button on click 
fun LoginUser() {
// Create an instance of signin service and get result to inform UI 
}

一个选项是创建一个接口并将其作为参数传递给EmailSignInService(callback) ,然后调用内部的相应方法addOnCompleteListenerLoginViewModel还必须实现接口并将逻辑放入相应的方法中。

有没有其他或更好的方法来处理这种情况?

标签: androidfirebasekotlinarchitecturefirebase-authentication

解决方案


您真的不想在 ViewModel 中处理 Firebase 事件。ViewModel 不应该了解数据源的实现细节。假设对您的数据源的抽象采取行动,通常通过具有所有实现细节的存储库对象公开的 LiveData 对象。LiveData 可以将来自 Firebase 任务对象的数据代理回 ViewModel。

一个非常粗糙的设计(你的应该更健壮并处理错误):

data class UserData {
    // information about the logged in user, copied from FirebaseUser
}

class UserRepository {
    fun newUser(): LiveData<UserData> {
        // Sign in with Firebase Auth, then when the Task is
        // complete, create a UserData using the data from
        // the auth callback, then send it to the LiveData
        // that was returned immediately
    }
}

class LoginViewModel : ViewModel() {
    private val repo = UserRepository()
    fun signInNewUser() {
        val live: LiveData<UserData> = repo.newUser()
        // observe the LiveData here and make changes to views as needed
    }
}

推荐阅读