You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:51:33