React中RecaptchaVerifier报错:无法在字符串'recaptcha-container'上创建属性'callback'
我有两个共享同一Firebase配置的应用,其中一个已成功实现signInWithPhoneNumber功能,但另一个应用出现报错:
RecaptchaVerifier Cannot create property 'callback' on string 'recaptcha-container'
页面中已添加对应容器:
<div id="recaptcha-container"></div>
核心代码如下:
const handleOTPRequest = (event) => { // 隐藏请求按钮 setRequestBtn(false); // 触发OTP请求 requestOTP(); }; const generateRecaptcha = () => { window.recaptchaVerifier = new RecaptchaVerifier( auth, "recaptcha-container", {} ); }; const requestOTP = (e) => { // e.preventDefault(); // 隐藏请求按钮 setRequestBtn(false); generateRecaptcha(); let appVerifier = window.recaptchaVerifier; let number = userNumber; signInWithPhoneNumber(auth, number, appVerifier) .then((confirmationResult) => { setConfirmationResult(confirmationResult); console.log(confirmationResult); }) .catch((err) => { console.log(err); }); }; const verifyOTP = () => { let otpCode = otp; if (confirmationResult && otpCode) { confirmationResult .confirm(otpCode) .then((result) => { // 用户登录成功 const user = result.user; console.log(user); dispatch(setCredentials(user.uid)); dispatch(setLogin(user.uid)); // 更新数据库 const addPhone = async () => { const userRef = doc(db, "users", user.uid); const userSnap = await getDoc(userRef); if (userSnap.exists()) { // 更新现有用户文档的phone字段 await setDoc(userRef, { ...userSnap.data(), // 保留现有属性 phone: user.phoneNumber, // 更新phone字段 }); dispatch(setMobile(user.phoneNumber)); navigate("/home"); } else { // 创建包含phone字段的新用户文档 await setDoc(userRef, { phone: user.email, }); dispatch(setEmail(user.email)); navigate("/home"); } }; addPhone(); // ... }) .catch((error) => { // 用户登录失败(验证码错误?) console.log(error); }); } };
1. DOM元素未加载完成就初始化Recaptcha
在React/Vue这类框架中,组件挂载完成前调用generateRecaptcha(),会导致recaptcha-container还没渲染到DOM里,Recaptcha无法找到容器。
解决:
直接传入DOM元素而非ID字符串,同时先校验元素存在:
const generateRecaptcha = () => { const container = document.getElementById("recaptcha-container"); if (!container) { console.error("找不到recaptcha容器元素"); return; } window.recaptchaVerifier = new RecaptchaVerifier( auth, container, {} ); };
如果是React,也可以把初始化逻辑放到useEffect钩子中,确保DOM挂载完成后执行。
2. 重复初始化或全局变量冲突
如果多次调用generateRecaptcha(),旧的verifier未销毁会导致冲突;或者其他脚本修改了recaptcha-container属性,也会引发错误。
解决:
初始化前先清理旧的verifier:
const generateRecaptcha = () => { if (window.recaptchaVerifier) { window.recaptchaVerifier.clear(); } const container = document.getElementById("recaptcha-container"); window.recaptchaVerifier = new RecaptchaVerifier(auth, container, {}); };
3. Firebase SDK版本不一致
两个应用共享配置,但SDK版本可能不同,新版本的RecaptchaVerifier参数规则有变化。
解决:
统一两个应用的Firebase SDK版本,比如在package.json中锁定版本:
"firebase": "^9.23.0"
4. 容器元素被隐藏或移除
如果recaptcha-container被设置为display: none,或者初始化前被动态移除,Recaptcha无法绑定到无效元素。
解决:
检查元素CSS状态,初始化时确保元素可见(可用visibility: hidden替代display: none,保留布局空间)。
内容的提问来源于stack exchange,提问作者Martin

