React Native函数组件跨屏传Firestore数据及auth.currentUser查询报错
问题解决路径
1. 修复.doc(firebase.auth().currentUser)触发的报错
这个写法的报错来自两个核心问题:
- 参数类型完全不匹配:Firestore的
.doc()方法要求入参是字符串格式的文档唯一ID,直接传入整个currentUser对象会被SDK直接拦截抛出类型错误。 - 缺少空值防护:
firebase.auth().currentUser是异步赋值的,应用冷启动阶段、用户未登录时这个值为null,哪怕取对了字段,没有空值判断的话,传入null同样会触发查询崩溃。
修正后的可运行写法:
// 错误写法(当前触发报错的写法) collection('userData').doc(firebase.auth().currentUser) // 写法1:同步场景带空值防护 const currentUser = firebase.auth().currentUser if (currentUser?.uid) { collection('userData').doc(currentUser.uid).get() } // 写法2:适配auth异步初始化的正确姿势,避免冷启动阶段取值为null useEffect(() => { // 监听auth状态变化,状态确认后再执行查询 const unsubscribeAuth = firebase.auth().onAuthStateChanged(user => { if (!user) return collection('userData').doc(user.uid).get() }) return () => unsubscribeAuth() }, [])
2. 跨屏幕传递Firestore数据的实现方案(适配你的const函数组件写法)
你当前使用接收props作为参数的const定义函数组件,不需要改动基础组件写法,根据实际场景选对应方案即可:
列表页跳详情页的1对1传值(匹配你现有代码逻辑)
你在BreadAndBounty.js中已经从adverts集合拉取了全量列表数据,FlatList渲染的每条item本身就是解析完成的Firestore文档(包含文档ID、所有业务字段),完全不需要在详情页重新发起单条数据查询。
- 列表页发起跳转时,直接把单条广告的解析后纯对象、对应Firestore文档ID通过导航路由参数传给详情页即可
适配代码示例:
// BreadAndBounty.js const BreadAndBounty = (props) => { // 原有拉取adverts集合、渲染FlatList的逻辑保持不变 const handleAdvertPress = (advertItem) => { // 跳转时传递导航库支持序列化的安全参数 props.navigation.navigate('AdvertsDetail', { advertData: advertItem, firestoreDocId: advertItem.id }) } return <FlatList data={advertList} renderItem={({ item }) => ( <AdvertCard onPress={() => handleAdvertPress(item)} /> )} /> }
- 详情页直接从props的路由参数中取数据,无需重复请求Firestore
// AdvertsDetail.js const AdvertsDetail = (props) => { // 从props中直接取列表页传递的数据 const { advertData, firestoreDocId } = props.route.params // 直接用这些字段渲染详情UI即可 }
无直接跳转关系的多屏数据共享
如果需要多个非嵌套屏幕共用同一份Firebase数据(比如全局用户资料、通用广告配置),可以把拉取到的Firestore数据存在轻量状态层(React Context、轻量状态管理库)中,因为你的组件本身是接收props的const写法,只需要把状态值通过props传递即可,不需要调整组件定义方式。
避坑提示:不要把Firestore原生的DocumentSnapshot、QuerySnapshot这类不可序列化的SDK对象直接当路由参数传递,导航库对传参的序列化有严格限制,只传输解析完成的纯JSON数据、字符串类型的文档ID这类可序列化内容即可。
内容的提问来源于stack exchange,提问作者Afonso Salvador
相关产品推荐
相关产品推荐

