React Native Firebase手机号认证发码后跳转OTP页出现不可序列化值警告
警告成因
React Navigation 要求所有路由参数必须是可序列化值(即可以被完整转换为JSON格式的类型,如字符串、数字、普通对象、数组等),不允许传递函数、类实例、Symbol等不可序列化类型。
你在登录页通过路由参数传递的confirmation是React Native Firebase返回的AuthConfirmationResult类实例,其内部包含多个内置方法(如你用到的confirm方法、警告中提到的_deleteApp方法),属于不可序列化值,因此触发了该警告。
该警告不是报错,短时间内不会影响功能运行,但如果你后续开启了导航状态持久化、深链接恢复等功能,会出现参数丢失、逻辑报错的问题。
解决方案
方案1:用全局状态存储confirm实例(最推荐)
使用全局状态管理工具(如Context、Redux、Zustand、MobX等)存储confirm实例,无需通过路由参数传递。
以下是用Zustand实现的示例代码:
// 新建全局状态文件 authStore.js import { create } from 'zustand' const useAuthStore = create((set) => ({ phoneConfirmInstance: null, setPhoneConfirmInstance: (instance) => set({ phoneConfirmInstance: instance }), clearPhoneConfirmInstance: () => set({ phoneConfirmInstance: null }), })) export default useAuthStore
修改登录页代码:
import useAuthStore from './authStore' async function signInWithPhoneNumber(phoneNumber) { try { const confirmation = await auth().signInWithPhoneNumber(phoneNumber); // 把实例存入全局状态 useAuthStore.getState().setPhoneConfirmInstance(confirmation) // 跳转时只传可序列化的手机号参数 props.navigation.navigate('OtpVerification', { phoneNo, }); } catch (error) { console.log(error); } }
修改OTP验证页代码:
import useAuthStore from './authStore' async function confirmCode() { // 从全局状态取实例 const confirm = useAuthStore.getState().phoneConfirmInstance if (otp) { try { await confirm.confirm(otp); // 验证完成后清空全局状态,避免内存泄漏 useAuthStore.getState().clearPhoneConfirmInstance() props.navigation.navigate('OnBoarding'); } catch (error) { AlertMsg('Invalid OTP'); } } else { AlertMsg('Please Enter OTP'); } }
方案2:挂载到全局变量(适合小型项目)
如果项目没有全局状态管理工具,可以临时把confirm实例挂载到全局变量上,用完后及时删除:
登录页代码:
async function signInWithPhoneNumber(phoneNumber) { try { const confirmation = await auth().signInWithPhoneNumber(phoneNumber); // 挂载到全局 global.phoneConfirmInstance = confirmation props.navigation.navigate('OtpVerification', { phoneNo, }); } catch (error) { console.log(error); } }
OTP验证页代码:
async function confirmCode() { const confirm = global.phoneConfirmInstance if (otp) { try { await confirm.confirm(otp); // 用完删除全局变量 delete global.phoneConfirmInstance props.navigation.navigate('OnBoarding'); } catch (error) { AlertMsg('Invalid OTP'); } } else { AlertMsg('Please Enter OTP'); } }
方案3:关闭当前路由的序列化检查(不推荐,治标不治本)
如果只是想快速消掉警告,可以在对应路由的配置中关闭序列化检查,但是后续如果用到导航状态持久化功能依然会出问题:
<Stack.Screen name="OtpVerification" component={OtpVerification} options={{ unmountOnBlur: true }} />
内容的提问来源于stack exchange,提问作者Juhi Kukreja
相关产品推荐
相关产品推荐

