Android 如何在单独的存储库(MVVM)中传递Firestore SnapshotListener提供的livedata
经过几个小时的努力和搜寻,我仍然被困在那里,希望有人能帮助我。 我试图通过ViewModel从Firestore(使用SnapshotListener)获取活动的实时更新,但所有尝试都失败了。下面是我当前的设置-尝试更新存储库中的LiveData并将其移交给视图模型 我的问题是: 我的Firestore集合中有UserData(在文档中)。我尝试使用observeUserData()函数在运行时侦听对当前用户的更改。此功能提供的数据(文档更改时)应通过my ViewModel发送到my Activity。如果我对Firestore中的用户文档更改了某些内容,SnapshotListener将按预期启动,但更新未到达我的ViewModel,因此未到达我的活动 有人能帮我存档吗?我现在看到的唯一解决方案是在我的ViewModel中添加SnapshotListener,但据我所知,这是一种糟糕的做法? 多谢各位 Firestore存储库Android 如何在单独的存储库(MVVM)中传递Firestore SnapshotListener提供的livedata,android,kotlin,google-cloud-firestore,android-livedata,android-mvvm,Android,Kotlin,Google Cloud Firestore,Android Livedata,Android Mvvm,经过几个小时的努力和搜寻,我仍然被困在那里,希望有人能帮助我。 我试图通过ViewModel从Firestore(使用SnapshotListener)获取活动的实时更新,但所有尝试都失败了。下面是我当前的设置-尝试更新存储库中的LiveData并将其移交给视图模型 我的问题是: 我的Firestore集合中有UserData(在文档中)。我尝试使用observeUserData()函数在运行时侦听对当前用户的更改。此功能提供的数据(文档更改时)应通过my ViewModel发送到my Acti
object FirestoreService {
val db = FirebaseFirestore.getInstance()
val userDataLiveData = MutableLiveData<UserData>()
fun observeUserData(userId: String) {
try {
db.collection("userData").document(userId).addSnapshotListener{ documentSnapshot: DocumentSnapshot?, firebaseFirestoreException: FirebaseFirestoreException? ->
firebaseFirestoreException?.let {
Log.e(TAG, firebaseFirestoreException.toString())
return@addSnapshotListener
}
val data = documentSnapshot?.toUserData()
data?.let {
Log.d(TAG, "post new value")
userDataLiveData.postValue(data)
}
}
} catch (e: Exception) {
Log.e(TAG, "Error getting user data", e)
}
}
//ViewModel Setup
val factory = MyViewModelFactory(user.uid.toString())
val viewModel = ViewModelProvider(this, factory).get(MyViewModel::class.java)
//Initialize UserData
viewModel.getUserData()
viewModel.userData.observe(this, Observer {
userData = it
Log.d(TAG, userData.toString())
})
您需要首先初始化viewModel
lateinit var userViewModel : MyViewModel
userViewModel = new ViewModelProvider(this).get(MyViewModel::class.java)
然后在userViewModel上使用getViewLifeCycleOwner方法,然后观察将包含userDataModel的LiveData
onChanged()方法可以访问userDataModel中的方法(getter和setter)有一种更简单的方法,无需任何侦听器。首先,添加此依赖项:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.9"
然后假设您拥有以下存储库:
inteface FirestoreService {
fun sendUserData(uid: String): LiveData<String> // Or whatever it should emit
}
在ViewModel中,您可以执行以下操作:
val myInput = "TestUUID"
val myUserID = sendUserData(myInput).asLiveData()
最后,在片段/活动中:
yourViewModel.myUserID.observe(viewLifecycleOwner) {
// do stuff here
}
谢谢大家的回复,幸运的是我发现了这个问题 我想我从不同的“指南”/“方法”中混淆了太多的东西-幸运的是,我在下面找到了道格·史蒂文森精彩的演讲,这让我摆脱了困境:
谢谢你,道格:)请编辑问题,更详细地解释这里的代码没有按你期望的方式工作。仅仅说它不起作用是不够的,我们需要调试信息。我建议阅读:嗨,道格,谢谢你的回复。我的Firestore集合中有UserData。我尝试使用observeUserData()函数在运行时侦听对当前用户的更改。此功能提供的数据(文档更改时)应通过my ViewModel发送到my Activity。如果我在Firestore中对我的用户更改了某些内容,SnapshotListener将启动,但是更新没有到达我的ViewModel,因此没有到达我的活动。嘿,Damola,谢谢你的回复。我已经在活动中初始化了ViewModel,只是错过了片段。将在上面编辑我的帖子://ViewModel Setup val factory=MyViewModelFactory(uid)val ViewModel=ViewModelProvider(这个,factory)。get(MyViewModel::class.java)嘿,安德鲁,我更新了我的协同程序播放服务-出于某种原因,它是在版本1.1.1-但不幸的是,这没有帮助。不太理解接口和实现部分的建议,仅仅对象是不够的吗?我的原始帖子中的“FirestoreService”对象是整个类。您关于sendUserData的建议听起来很有趣,但对于上述实现,我在调用函数时只会收到一次文档-但我想在Firestore中对文档更改进行“实时更新”-您知道如何存档吗?@Sebastian您说得对,我错过了这一部分,抱歉。正如它所展示的,我会提到如何通过协同程序实现实时侦听器。嗨,安德鲁,谢谢。我尽量避免在ViewModel中调用数据库,因为(如果我理解正确,对MVVM体系结构来说是非常新的),我不应该混淆数据库和ViewModel部分——或者在这一点上我错了吗?我只是想知道。。。如果我只想获得一个文档/值,我的设置就可以了。我就是无法让这些更新生效。这家伙的演示题为“Firebase和Android Jetpack:像手套一样合身”。这是完全相反的。我是唯一一个觉得这件事过于复杂和复杂的人吗?
fun sendUserData(uid: String): Flow<String> = flow {
val mySnapshot = db.collection("userData)".document(userId).await()
emit(mySnapshot?.toUserData)
}
val myInput = "TestUUID"
val myUserID = sendUserData(myInput).asLiveData()
yourViewModel.myUserID.observe(viewLifecycleOwner) {
// do stuff here
}