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

Firebase OTP重发时仍获相同验证码,无法判断过期问题求助

Firebase OTP重发后验证码重复问题解决方法

问题核心原因

  1. 手机号格式不一致:首次请求和重发请求的手机号格式存在差异(首次带空格和末尾的点,重发无空格但带点),多余标点可能干扰Firebase验证逻辑,导致复用旧验证码。
  2. 未同步更新Verification ID:重发OTP后生成了新的verificationID,但未同步到校验页面,导致校验时仍使用旧ID,而旧ID对应的OTP未过期时,Firebase会返回相同验证码。
  3. Resend Token未更新:重发后未更新resendToken,后续重发仍用旧token,无法触发Firebase生成新OTP。

具体修复步骤

1. 统一手机号格式,移除多余标点

无论首次请求还是重发,手机号必须保持一致且无多余符号:

  • 首次请求修改:
phoneNumber: "+$countryCode${phoneController.text}", // 去掉空格和末尾的点
  • 重发请求修改:
phoneNumber: "+${widget.countryCode}${widget.number}", // 去掉末尾的点

2. 重发后同步更新Verification ID和Resend Token

在OTP页面添加回调函数,将新生成的verificationID和resendToken同步到父组件,确保后续校验使用最新值:

  • 修改OTPWidget构造函数,增加回调参数:
class OTPWidget extends StatefulWidget {
  final String number;
  final String verificationId;
  final String countryCode;
  final int? resendToken;
  final String? smsCode;
  final Function(String, int) onResendSuccess; // 新增同步回调

  const OTPWidget({
    Key? key,
    required this.number,
    required this.verificationId,
    required this.countryCode,
    this.resendToken,
    this.smsCode,
    required this.onResendSuccess,
  }) : super(key: key);

  @override
  State<OTPWidget> createState() => _OTPWidgetState();
}
  • 重发OTP函数的codeSent回调中同步新值:
await _auth.verifyPhoneNumber(
  phoneNumber: "+${widget.countryCode}${widget.number}",
  verificationCompleted: (phoneAuthCredential) async {
    setState(() => showLoading = false);
  },
  verificationFailed: (verificationFailed) {
    setState(() => showLoading = false);
    print(verificationFailed.code);
  },
  forceResendingToken: widget.resendToken,
  codeSent: (verificationID, resendingToken) async {
    setState(() {
      showLoading = false;
      _isButtonDisabled = true;
      this.verificationID = verificationID;
    });
    // 同步新ID和Token到父组件
    widget.onResendSuccess(verificationID, resendingToken);
  },
  codeAutoRetrievalTimeout: (verificationID) async {}
);
  • 首次跳转OTPWidget时传递回调:
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => OTPWidget(
      number: phoneController.text,
      verificationId: verificationID,
      countryCode: countryCode,
      resendToken: _resendToken,
      smsCode: otpValue,
      onResendSuccess: (newVerificationId, newResendToken) {
        setState(() {
          verificationID = newVerificationId;
          _resendToken = newResendToken;
        });
      },
    ),
  ),
);

3. 校验OTP时使用最新的Verification ID

确保校验环节优先使用本地更新后的ID:

AuthCredential phoneAuthCredential = PhoneAuthProvider.credential(
  verificationId: this.verificationID ?? widget.verificationId,
  smsCode: otpController.text
);

额外注意事项

  • 避免缓存verificationID或OTP值,每次重发后依赖回调更新的最新值。
  • 若问题仍存在,检查Firebase控制台的验证设置,确保OTP过期时间配置合理(默认300秒)。

内容的提问来源于stack exchange,提问作者Gaurav Patil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:20:14