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

React 18集成Firebase OTP认证遇auth/argument-error错误求助

React 18 + Firebase OTP认证中reCAPTCHA引发的auth/argument-error错误

我在React 18应用中基于Firebase实现OTP认证功能,流程为用户输入手机号后接收OTP,验证成功后补充邮箱、密码和用户名信息。目前遇到与reCAPTCHA验证相关的FirebaseError: Firebase: Error (auth/argument-error)错误,即使将reCAPTCHA初始化代码移出useEffect仍无法解决。

相关代码

全局声明

declare global {
  interface Window {
    recaptchaVerifier: RecaptchaVerifier;
  }
}

初始化reCAPTCHA

const initializeRecaptcha = () => {
  if (!window.recaptchaVerifier) {
    window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
      size: 'normal',
      callback: (response: any) => {
        handleSendOtp();
      },
      'expired-callback': () => {
        console.error('reCAPTCHA过期,请重试。');
      }
    });
    window.recaptchaVerifier.render().catch((error) => {
      console.error('初始化reCAPTCHA出错', error);
    });
  }
};

useEffect初始化reCAPTCHA

useEffect(() => {
  if (open) {
    initializeRecaptcha();
  }
}, [open]);

发送OTP

const handleSendOtp = async () => {
  if (isSending) return;

  setIsSending(true);
  try {
    const appVerifier = await window.recaptchaVerifier;
    const formattedPhoneNumber = formatPhoneNumber(phoneNumber);
    if (!formattedPhoneNumber) {
      console.error('手机号格式无效');
      setIsSending(false);
      return;
    }
    const result = await signInWithPhoneNumber(auth, formattedPhoneNumber, appVerifier);
    setConfirmationResult(result);
  } catch (error: any) {
    console.error('发送OTP出错', error);
    if (error.code === 'auth/too-many-requests') {
      console.error('请求次数过多,请稍后重试。');
    }
  } finally {
    setIsSending(false);
  }
};

验证OTP

const handleVerifyOtp = async () => {
  if (!confirmationResult) return;

  try {
    const result = await confirmationResult.confirm(otp);
    onVerified(result.user.phoneNumber!);
  } catch (error) {
    console.error('验证OTP出错', error);
  }
};

浏览器错误信息

Unexpected Application Error!
Firebase: Error (auth/argument-error).
FirebaseError: Firebase: Error (auth/argument-error).
    at createErrorInternal (http://localhost:3000/node_modules/.vite/deps/firebase_auth.js?

解决建议

  1. 移除appVerifier前的await
    window.recaptchaVerifier是同步创建的实例,不是Promise,无需用await。修改代码:

    const appVerifier = window.recaptchaVerifier;
    

    这是最可能引发参数错误的原因——错误地将非Promise值用await处理,导致appVerifier无效,传给signInWithPhoneNumber时触发参数错误。

  2. 确保DOM容器存在
    调用initializeRecaptcha前,确认recaptcha-container元素已挂载到DOM。如果是弹窗组件,可在初始化前加判断:

    const initializeRecaptcha = () => {
      const container = document.getElementById('recaptcha-container');
      if (!container || window.recaptchaVerifier) return;
      // 后续初始化逻辑
    };
    
  3. 清理旧实例
    弹窗关闭时,清理reCAPTCHA实例避免冲突:

    useEffect(() => {
      if (open) {
        initializeRecaptcha();
      } else {
        window.recaptchaVerifier?.clear();
        delete window.recaptchaVerifier;
      }
    }, [open]);
    
  4. 验证Auth实例有效性
    确认auth实例是通过getAuth(app)正确初始化的,且在调用RecaptchaVerifier前已完成初始化。

内容的提问来源于stack exchange,提问作者Rida Fatima

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:07:04