React+Vite集成Firebase手机号OTP认证报错排查求助
问题
在React+Vite项目中实现基于Firebase的手机号OTP认证时,遇到错误:TypeError: Cannot read properties of undefined (reading 'appVerificationDisabledForTesting')。
相关代码实现如下:
firebaseConfig.jsx 文件
import { initializeApp } from 'firebase/app'; import { getAuth } from 'firebase/auth'; const firebaseConfig = { apiKey: "", authDomain: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "", measurementId: "" }; const firebaseApp = initializeApp(firebaseConfig); const auth = getAuth(firebaseApp) export { firebaseApp, auth };
signup.jsx 组件页面
import { auth } from '../../../../firebaseConfig/firebaseConfig'; import { RecaptchaVerifier, signInWithPhoneNumber } from 'firebase/auth'; const [formValues, SetValues] = useState({ name: '', email: '', phone: '', password: '', confirmPassword: '' }) const [confirmationResult, setConfirmationResult] = useState(null) const handleSendOtp = async () => { try { const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', { size: 'invisible', callback: () => { console.log('recaptcha resolved..') } }, auth) signInWithPhoneNumber(formValues.phone, recaptchaVerifier).then((result) => { setConfirmationResult(result); alert("code sent") setshow(true); }) .catch((err) => { alert(err); window.location.reload() }); } catch (error) { flag = false console.log('error sending otp ' + error) } }
Recaptcha容器写法
return( <> <div id='recaptcha-container'></div> //此处根据confirmationResult状态条件渲染组件 {confirmationResult===null?(<component1.....lines>):(<component2.....lines>)} </> )
已检查导入导出语句、Firebase应用初始化,查阅相关文档仍未找到问题所在,疑问:是否是RecaptchaVerifier或容器设置存在问题?
解决方案
确保Recaptcha容器DOM已挂载
错误核心原因是创建RecaptchaVerifier时,recaptcha-container元素还未被React渲染到DOM中。可以通过两种方式解决:- 在
handleSendOtp中先检查元素是否存在:const handleSendOtp = async () => { const container = document.getElementById('recaptcha-container'); if (!container) { console.error('Recaptcha容器未找到'); return; } // 后续创建RecaptchaVerifier的逻辑 } - 使用React的
useRef获取容器元素,避免依赖DOM ID:import { useRef } from 'react'; const recaptchaRef = useRef(null); // 在return中: <div ref={recaptchaRef}></div> // 在handleSendOtp中: const recaptchaVerifier = new RecaptchaVerifier(recaptchaRef.current, { size: 'invisible', callback: () => console.log('recaptcha resolved..') }, auth);
- 在
避免重复创建RecaptchaVerifier
多次调用handleSendOtp会重复创建实例引发冲突,可将实例存储在useRef中确保只创建一次:const recaptchaVerifierRef = useRef(null); useEffect(() => { recaptchaVerifierRef.current = new RecaptchaVerifier('recaptcha-container', { size: 'invisible', callback: () => console.log('recaptcha resolved..') }, auth); return () => { recaptchaVerifierRef.current?.clear(); // 组件卸载时清理 }; }, [auth]); // 在handleSendOtp中使用已创建的实例 if (!recaptchaVerifierRef.current) return; signInWithPhoneNumber(formValues.phone, recaptchaVerifierRef.current) // ...后续逻辑检查手机号格式
确保formValues.phone符合E.164标准格式(例如+8613800138000),格式错误可能间接触发相关异常。验证Auth实例有效性
在创建RecaptchaVerifier前确认auth实例正常:if (!auth) { console.error('Firebase Auth实例未初始化'); return; }
内容的提问来源于stack exchange,提问作者Adil Salah
相关产品推荐
相关产品推荐

