如何观察viewmodel中的数据?

How to observe data inside viewmodel?

我已将我的 android 应用程序连接到 firebase,并使用它从 firestone 检索身份验证详细信息和数据。为此,我正在使用 MVVM 架构和实时数据。问题是我需要先检索电子邮件地址,然后使用此数据查询包含 ID = emailID 文档的火石。你可以看到我的视图模型。每次我 运行 时,emailID 的值为 null。如何在遵循 MVVP 编码风格的同时完成此任务?

#Edit:我需要了解在一个实时数据值依赖于另一个的情况下如何检查实时数据是否已用值初始化。

class ProfileViewModel(): ViewModel() {

    var random =""
    private var _name = MutableLiveData<String>()
    val userName
        get()=_name

    private  var _post = MutableLiveData<String>()
    val userPost
        get()=_post

    private var _imgUrl = MutableLiveData<Uri>()
    val userImgUrl
        get()=_imgUrl

    private var _emailId = MutableLiveData<String>()
    val userEmailId
        get()=_emailId


    init{

        getUserDataFromProfile()
        getUserPostFromFirestone()

    }

    private fun getUserPostFromFirestone() {


        val mDatabaseInstance: FirebaseFirestore = FirebaseFirestore.getInstance()
//        _emailId.observe(getApplication(), Observer {
//
//        } )
        if(_emailId.value!=null){
            mDatabaseInstance.collection("users").document(_emailId.value)
                .get()
                .addOnCompleteListener { task ->
                    if (task.isSuccessful) {
                        _post.value = task.result?.data?.get("post").toString()

                    } else {
//                    Log.w("firestone", "Error getting documents.", task.exception)
                        _post.value = "Unable to Retrieve"
                    }
                }
        }
    }

    private fun getUserDataFromProfile() {

        val mAuth = FirebaseAuth.getInstance()

        val currentUser = mAuth.currentUser
        random = currentUser?.displayName!!
        _name.value = currentUser?.displayName

        _post.value = "Unknown"
        _imgUrl.value = currentUser?.photoUrl
        _emailId.value = currentUser?.email


    }


}

你可以把observer设置成LiveData,不需要的时候再去掉:

class ProfileViewModel : ViewModel() {

    private val _email = MutableLiveData<String>()

    private val emailObserver = Observer<String> { email ->
        //email is here
    }

    init {
        _email.observeForever(emailObserver)
    }

    override fun onCleared() {
        _email.removeObserver(emailObserver)
        super.onCleared()
    }
}

尝试使用协程来顺序执行代码。所以一旦你得到一个的输出然后第二个开始执行。如果这不起作用请告诉我我可以帮助你。

 init{
    viewModelScope.launch{
            getUserDataFromProfile()
            getUserPostFromFirestone()
    }
   }

如果您在 Firebase 调用上编写包装器并将其公开为 LiveData(或者,在这种情况下,我会假装它被包装在 suspendCoroutineCancellable 中),在这种情况下,无论何时您想要链接东西,您要么需要 MediatorLiveData 将多个 LiveData 组合成一个流(参见 this library I wrote for this specific purpose),要么只需要 switchMap.

private val auth = FirebaseAuth.getInstance()

val imgUrl: LiveData<Uri> = MutableLiveData<Uri>(auth.currentUser?.photoUrl)
val emailId: LiveData<String> = MutableLiveData<String>(auth.currentUser?.email)

val post = emailId.switchMap { emailId -> 
    liveData {
        emit(getUserByEmailId(emailId))
    }
}