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

Firebase手机号认证为何在本机号码验证时失效?

问题描述

使用Flutter开发应用,基于Firebase Auth实现手机号认证。特定手机号能正常接收短信验证码,但输入验证码时提示无效;换用其他设备的号码认证时,验证码可正常通过验证。已在多台设备测试,问题一致。

相关代码如下:

手机号认证发起逻辑:

void phonenumberauth(String PhoneNumber) async {
    await auth.verifyPhoneNumber(
      phoneNumber: PhoneNumber,
      verificationCompleted: (PhoneAuthCredential credential) async {
        // Get.dialog(Center(child: CircularProgressIndicator(),));
        await auth.signInWithCredential(credential);
      },
      verificationFailed: (FirebaseAuthException e) {
        if (e.code == 'invalid-phone-number') {
          Get.snackbar('Error', 'the provided phone number in not valid ');
        } else {
          Get.snackbar('Error', '${e.message}');
        }
      },
      codeSent: (verificationId, int? resendToken) {
        this.verificationId.value = verificationId;
      },
      codeAutoRetrievalTimeout: (String verificationId) {
        this.verificationId.value = verificationId;
      },
    );
  }

验证码验证逻辑:

Future<bool> verifyOTP(String otp) async {
    var credentials = await auth.signInWithCredential(
        PhoneAuthProvider.credential(
            verificationId: verificationId.value, smsCode: otp));
    return credentials.user != null ? true : false;
  }

验证后跳转逻辑:

Future<bool?> verifiyOTP(String otp) async {
    //CollectionReference usersCollection = FirebaseFirestore.instance.collection('users');
    var isVerified = await Auth_controller.instance.verifyOTP(otp);
    String? userId = Auth_controller.instance.user?.uid;
    //var userDoc = await usersCollection.doc(userId).get();
    isVerified ? Get.offAll(SignupPhoneNumber()) : Get.back();
  }
}

排查与解决方法

1. 重置verificationId避免旧值干扰

从代码看verificationId是GetX响应式变量,若每次发起认证前未重置,可能残留旧的ID,导致用旧ID验证新验证码时失效。

修改phonenumberauth方法,添加重置逻辑:

void phonenumberauth(String PhoneNumber) async {
    // 重置verificationId,清除旧值
    verificationId.value = "";
    await auth.verifyPhoneNumber(
      // 原有代码逻辑
    );
  }

2. 排查自动验证回调的冲突

verificationCompleted会在设备自动读取验证码并完成登录时触发,若你的测试设备支持自动填充,此时手动输入验证码会因为用户已处于登录状态,再次调用signInWithCredential导致会话冲突,验证码被判无效。

可暂时注释自动登录逻辑测试:

verificationCompleted: (PhoneAuthCredential credential) async {
    // 暂时注释,测试手动验证流程
    // await auth.signInWithCredential(credential);
  },

测试有效后,再根据业务需求调整自动验证的触发条件(比如仅在用户未手动输入时执行自动登录)。

3. 检查Firebase控制台的号码限制

该手机号可能因多次测试、异常操作被Firebase风控标记,导致验证失败:

  • 登录Firebase控制台,进入Authentication > 登录方法 > 手机号,检查是否有相关限制配置
  • 进入Authentication > 用户,删除该手机号对应的测试用户,重新发起认证

4. 确保手机号格式完全一致

确认发起认证时的手机号格式(比如带国家码、无空格/特殊字符)统一,避免因格式差异导致验证不匹配,例如统一使用+8613xxxxxxxxx格式。

5. 捕获验证时的具体错误信息

当前verifyOTP未捕获异常,无法定位具体错误原因,添加异常捕获输出错误码:

Future<bool> verifyOTP(String otp) async {
    try {
      var credentials = await auth.signInWithCredential(
          PhoneAuthProvider.credential(
              verificationId: verificationId.value, smsCode: otp));
      return credentials.user != null;
    } on FirebaseAuthException catch (e) {
      print("OTP验证错误:${e.code} - ${e.message}");
      Get.snackbar('验证失败', '${e.message}');
      return false;
    }
  }

根据输出的错误码(如invalid-verification-code、session-expired),可精准定位问题。


内容的提问来源于stack exchange,提问作者mehdi aribi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:22:33