如何观察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))
}
}
我已将我的 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))
}
}