android - ViewModel 和 LiveData 不会立即从 Firebase 实时数据库中获取更改
问题描述
为了从我的 Firebase 实时数据库中读取数据,我同时使用 aLiveData
和ViewModel
.
LiveData
:
class FirebaseQueryLiveData(ref: DatabaseReference) : LiveData<DataSnapshot>() {
private val query: Query = ref
private val listener: MyValueEventListener = MyValueEventListener()
private var listenerRemovePending = false
private val removeListener = object : Runnable {
override fun run() {
query.removeEventListener(listener)
listenerRemovePending = false
}
}
override fun onActive() {
super.onActive()
if (listenerRemovePending) {
Handler(Looper.getMainLooper()).removeCallbacks(removeListener)
} else {
query.addValueEventListener(listener)
}
listenerRemovePending = false
}
override fun onInactive() {
super.onInactive()
Handler(Looper.getMainLooper()).postDelayed(removeListener, 2000)
query.removeEventListener(listener)
}
private inner class MyValueEventListener : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
value = snapshot
}
override fun onCancelled(error: DatabaseError) {
return
}
}
}
ViewModel
:
class UsersViewModel : ViewModel() {
private val uid = Firebase.auth.currentUser!!.uid
private val USERS_REF: DatabaseReference = FirebaseDatabase.getInstance().getReference("/users/$uid")
private val liveData: FirebaseQueryLiveData = FirebaseQueryLiveData(USERS_REF)
private val usersLiveData: MediatorLiveData<Users> = MediatorLiveData()
init {
usersLiveData.addSource(liveData, object : Observer<DataSnapshot> {
override fun onChanged(dataSnapshot: DataSnapshot?) {
if (dataSnapshot != null) {
usersLiveData.postValue(dataSnapshot.getValue(Users::class.java))
} else {
usersLiveData.value = null
}
}
})
}
@NonNull
fun getUsersLiveData() : LiveData<Users> {
return usersLiveData
}
@NonNull
fun removeUsersLiveData() {
USERS_REF.removeValue()
}
}
为了在我的片段/活动中读取我的 Firebase 实时数据库,我执行以下操作:
val usersViewModel = ViewModelProvider(this).get(UsersViewModel::class.java)
val usersLiveData = usersViewModel.getUsersLiveData()
usersLiveData.observe(viewLifecycleOwner, object : Observer<Users> {
override fun onChanged(users: Users?) {
if (users != null) {
firstName = users.firstName
lastName = users.lastName
today = users.today.toString()
week = users.week.toString()
}
}
})
为了在我的片段/活动中写入我的 Firebase 实时数据库,我执行以下操作:
val updateUserChildValues = Firebase.database.getReference("users").child(auth.currentUser!!.uid)
updateUserChildValues.child("child-name").setValue(value)
现在的问题是当我更新数据库中的值时,有时侦听器不会立即获取更改。我要么必须去另一个破坏前一个活动的活动,回到旧活动,这样我才能看到新的变化,要么关闭应用程序并再次打开它。所以基本上应用程序需要刷新片段/活动来获得新的变化。
我应该怎么办?如何确保侦听器始终从我的数据库中获取新更改,以便立即更新 UI?或者我如何刷新我的片段/活动以确保用户总是立即看到新的变化?
解决方案
推荐阅读
- jquery - 删除列表中的项目
- javascript - 获取数据后如何获取数据更新数据以显示在vue中
- java - spring @value 与可执行 jar 外部的属性文件一起使用
- c# - 如何从 restFull Web 服务发送图像?
- javascript - 反应表不显示数据
- c++ - 涉及依赖注入时如何使用组合而不是继承?
- android - W/SyncTree:在 /users 处侦听失败:DatabaseError:权限被拒绝
- android - 在某些设备上未获得适用于 Android 图像的 reCAPTCHA
- android - 将时间选择器限制为两个小时之间的时间选择
- angular - Angular 2 ViewChild NgModel 设置新值