Expo中Firebase实时数据库查询后无法获取正确文本格式问题求助
解决Expo中Firebase实时数据库店铺详情与名称获取问题
问题分析
你的查询路径food/{paramKey}已经定位到具体店铺的详情节点(比如food/Bakery/Bakery Cuisine),这个节点的子项就是单个详情字段(如Description、Address)。你用snapshot.forEach遍历的是这些字段,所以child.val()就是字段的直接值,不是包含Description的对象,这才会出现child.val().Description返回undefined的情况。
解决方案
1. 获取店铺详情字段内容
直接通过snapshot.val()获取整个店铺的详情对象,无需遍历子字段:
import { ref, onValue } from "firebase/database"; import { database } from "../firebaseConfig"; // 你的Firebase配置文件 // 从路由参数获取传递的路径(如"Bakery/Bakery Cuisine") const paramKey = route.params.paramKey; const shopRef = ref(database, `food/${paramKey}`); onValue(shopRef, (snapshot) => { if (snapshot.exists()) { const shopDetails = snapshot.val(); // shopDetails包含所有详情字段,可直接通过shopDetails.Description、shopDetails.Address调用 console.log("店铺详情:", shopDetails); } else { console.log("未找到该店铺数据"); } }, (error) => { console.error("查询错误:", error); });
如果需要动态渲染所有详情字段,可使用snapshot.forEach遍历,此时child.key是字段名,child.val()是对应值:
onValue(shopRef, (snapshot) => { if (snapshot.exists()) { const detailsList = []; snapshot.forEach((child) => { detailsList.push({ fieldName: child.key, // 例如"Description" fieldValue: child.val() // 对应的详情文本 }); }); console.log("所有详情字段:", detailsList); } });
2. 获取并展示店铺名称
你传递的paramKey是cuisine/店铺名称格式,分割路径取最后一段即可得到店铺名:
// 从路由参数提取店铺名称 const paramKey = route.params.paramKey; const shopName = paramKey.split("/").pop(); // 页面中直接渲染 return ( <View> <Text style={{ fontSize: 20, fontWeight: "bold" }}>{shopName}</Text> {/* 直接渲染指定详情字段 */} <Text>描述:{shopDetails?.Description}</Text> {/* 或动态渲染所有字段 */} {detailsList?.map((item) => ( <Text key={item.fieldName}>{item.fieldName}:{item.fieldValue}</Text> ))} </View> );
完整示例代码片段
import React, { useState, useEffect } from "react"; import { View, Text } from "react-native"; import { ref, onValue } from "firebase/database"; import { database } from "../firebaseConfig"; const SubScreen3 = ({ route }) => { const [shopName, setShopName] = useState(""); const [shopDetails, setShopDetails] = useState({}); useEffect(() => { const paramKey = route.params.paramKey; // 提取店铺名称 const name = paramKey.split("/").pop(); setShopName(name); // 监听店铺详情数据 const shopRef = ref(database, `food/${paramKey}`); const unsubscribe = onValue(shopRef, (snapshot) => { if (snapshot.exists()) { setShopDetails(snapshot.val()); } else { setShopDetails({}); console.log("店铺数据不存在"); } }); // 组件卸载时取消监听 return () => unsubscribe(); }, [route.params]); return ( <View style={{ padding: 20 }}> <Text style={{ fontSize: 24, fontWeight: "bold", marginBottom: 20 }}> {shopName} </Text> {/* 遍历所有详情字段并渲染 */} {Object.entries(shopDetails).map(([key, value]) => ( <Text key={key} style={{ fontSize: 16, marginBottom: 10 }}> {key}: {value} </Text> ))} </View> ); }; export default SubScreen3;
内容的提问来源于stack exchange,提问作者L.Calvin
相关产品推荐
相关产品推荐

