提问人:HaBuiDuc 提问时间:11/13/2023 最后编辑:Frank van PuffelenHaBuiDuc 更新时间:11/13/2023 访问量:46
如何使用 id 从 Firebase RealTimeDatabase 获取数据
How to get data from Firebase RealTimeDatabase using id
问:
我正在构建一个食品订购应用程序,我有一个 CartItem 列表
data class CartItemData(
@PrimaryKey
val cartItemId: String = UUID.randomUUID().mostSignificantBits.toString(),
val userId: String,
val foodId: String,
val price: Double,
val quantity: Int)
我想使用 cartItem 中的食物 ID 从 Firebase 实时数据库中检索食物数据,然后将其显示给用户。
这是我从数据库中获取食物数据的代码
fun getFood(
foodId: String,
onGetFoodSuccess: (FoodData) -> Unit
) {
foodsRef.orderByChild("id").equalTo(foodId).addListenerForSingleValueEvent(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
snapshot.children.forEach { shot ->
Log.d(TAG, shot.value.toString())
val data = shot.getValue(FoodData::class.java)
data?.let(onGetFoodSuccess)
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
这是我的购物车视图模型
class CartViewModel : ViewModel() {
private val fireBaseRepository = FireBaseRepository.get()
private val cartRepository = CartRepository.get()
private val _cartState = MutableStateFlow(CartState())
val cartState: StateFlow<CartState> = _cartState.asStateFlow()
init {
getCart()
}
fun getFood(
foodId: String,
onGetFoodSuccess: (FoodData) -> Unit
) {
fireBaseRepository.getFood(
foodId = foodId,
onGetFoodSuccess = onGetFoodSuccess
)
}
private fun getCart() {
viewModelScope.launch {
cartRepository.getCart().collect {cartItems ->
_cartState.value = _cartState.value.copy(
cartItems = cartItems,
)
}
}
}
}
我不知道如何从实时数据库中检索数据并在从 SQLite 数据库中获取购物车数据后将其传递到我的视图。
答:
0赞
Pablo
11/13/2023
#1
首先,我强烈建议您检查firebase是否正确检索快照,否则您的配置可能会有问题。此外,如果此时:
// code ...
foodsRef.orderByChild("id").equalTo(foodId).addListenerForSingleValueEvent(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
snapshot.children.forEach { shot ->
Log.d(TAG, shot.value.toString())
val data = shot.getValue(FoodData::class.java)
data?.let(onGetFoodSuccess)
}
}
override fun onCancelled(error: DatabaseError) {
}
})
//code ...
这个日志正在检索数据,我可以假设主要问题出在这张地图上:,可能你打得不好,
因此,此值为 null 并且不回调。我的建议是检查firebase的快照结果,并检查您的数据类是否定义正确,提醒设置其默认值,否则应用程序将崩溃。查看此文档以获取更多解释。val data = shot.getValue(FoodData::class.java)
FoodData
现在,如果你的问题是处理回调以检索到UI,那就更简单了。 您可以在 compose 视图中使用 cartState,并将 collect 作为可组合项的状态,因此每次此 stateFlow 更改其值时,都会重新绘制可组合项,请查看: https://developer.android.com/jetpack/compose/state#use-other-types-of-state-in-jetpack-compose
评论
0赞
HaBuiDuc
11/13/2023
我的 FoodData 定义正确,我的 getFood 函数正确检索数据,并且数据不为 null。但是,我尝试在 cartState 中定义一个 FoodData 列表并在成功检索 cartItemData 时更新它,但我的可组合项没有侦听 foodData 更新。不过,它可以接收带有 cartItemData 的更新。
0赞
Pablo
11/13/2023
尝试使用 stateFlow,就像您用于 _cartState 一样,但现在用于 getFood。并在 ui 上使用它,例如: ' fun getFood( foodId: String, ) { fireBaseRepository.getFood( foodId = foodId, onGetFoodSuccess = { _foodState.value = it } ) } '
0赞
HaBuiDuc
11/13/2023
它仍然不起作用。我的 UI 无法接收来自 FoodData 的更新。此外,我只声明了一个 cartState 变量来存储 CartScreen 的状态。我需要foodData来显示食物的名称和图像,因为我只将foodId存储在CartItem中。
0赞
Pablo
11/13/2023
所以你需要一个新的状态来重新组合并正确显示新数据,我认为你误解了可组合状态,你需要更新这个状态来用新数据更新组合。您需要调用此方法 getFood 并更新新的状态变量_foodState并在要使用 FoodData 的屏幕中使用它,这应该足够了。此外,分享您正在使用状态变量的屏幕代码。
0赞
HaBuiDuc
11/13/2023
但我认为 cartState 是一种状态,它的每次更改都会触发 UI。我以这种方式编写了一些状态,它工作得很好,我只对这个视图模型有问题。此外,请检查我的新问题以清楚地查看代码,因为我在此问题中没有提供 cartState 类。
评论