android - 使用 ViewModel 和 LiveData 时如何设置 Firebase 实时数据库的子值?
问题描述
我有以下内容data class
,其中包含 Firebase 实时数据库中特定引用的子值:
data class Users(
val uid: String = "",
var firstName: String = "",
var lastName: String = "",
)
这是我的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
}
}
这是我的扩展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
}
}
}
Activity
为了在我的or中读取我的数据库中的值Fragment
,这就是我所做的:
val usersViewModel = ViewModelProvider(this).get(UsersViewModel::class.java)
val usersLiveData = usersViewModel.getUsersLiveData()
usersLiveData.observe(this, object : Observer<Users> {
override fun onChanged(users: Users?) {
if (users != null) {
firstNameTextView.text = users.firstName
lastNameTextView.text = users.lastName
}
}
})
这一切都有效,但我的问题是如何在我的Activity
or中为我的数据库写一个特定的孩子Fragment
?例如,假设我只想修改lastName
孩子?我怎么做?FirebaseDatabase
我的活动和片段中没有任何引用,因为ViewModel
并LiveData
确保我不再需要它们。
解决方案
推荐阅读
- google-cloud-platform - GCP Notebook AI -- 具有写入权限的 SSH?
- java - 如何在android studio中显示一次性吐司消息
- javascript - 如何检查一个字符串是否仅包含数组项?
- docker - Docker + Nginx + 几个带有反向代理的站点;目录绑定问题
- julia - 如何从 Julia 中的文件名中提取扩展名?
- git - Git命令在init容器中不起作用
- python - 将具有选定列的数据框转换为具有指标值的值列
- python - 解析存储为 XML 的足球统计数据
- reactjs - React Firebase登录,显示白屏而不是主页
- json - 如何在按钮单击时调用发布功能