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

Firebase手机号验证崩溃:无法创建PhoneAuthCredential报错

解决Firebase手机号验证时的IllegalArgumentException崩溃问题

我之前在做Firebase Phone Auth的时候也碰到过一模一样的崩溃,这个错误其实就是在创建PhoneAuthCredential时参数没传对导致的,给你梳理下问题原因和解决办法:

问题根源

报错提示的Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, or temporary proof,翻译过来就是:创建PhoneAuthCredential必须提供验证凭证、会话信息或者临时证明。说白了就是你调用PhoneAuthProvider.getCredential()的时候,缺少了必填的核心参数——要么是「验证ID + 用户输入的验证码」,要么是自动验证返回的完整凭证。

具体解决步骤

1. 先确认你的验证码流程是否正确

Firebase的手机号验证分为两种场景,对应不同的凭证创建方式:

  • 自动验证场景:当设备能自动读取短信验证码时,Firebase会在onVerificationCompleted回调里直接返回一个完整的PhoneAuthCredential,你直接用这个凭证去登录就行,不需要自己再调用getCredential()。
  • 手动输入验证码场景:需要先在onCodeSent回调里拿到verificationId(验证ID),等用户输入验证码后,把verificationId和用户输入的验证码一起传给getCredential()。

2. 检查代码里的常见错误点

  • 有没有在还没拿到verificationId的时候就去调用getCredential()?比如在verifyPhoneNumber刚调用完就执行创建凭证的代码,这时候onCodeSent还没触发,verificationId是空的,肯定会报错。
  • 有没有把verificationId或者验证码的变量写错?比如变量名拼写错误,导致传入了空值。
  • 有没有在屏幕旋转等配置更改后丢失了verificationId?这时候需要把verificationId存在SavedInstanceState里,避免重建Activity后变量清空。

正确代码示例

发送验证码的核心代码

// 初始化手机号验证
PhoneAuthProvider.getInstance().verifyPhoneNumber(
        "+1234567890",  // 要验证的手机号,记得加国家区号
        60,             // 验证码有效期(秒)
        TimeUnit.SECONDS,
        this,           // 当前Activity上下文
        new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            // 自动验证成功(设备自动读取短信)
            @Override
            public void onVerificationCompleted(PhoneAuthCredential credential) {
                // 直接用这个凭证登录
                signInWithPhoneAuthCredential(credential);
            }

            // 验证失败
            @Override
            public void onVerificationFailed(FirebaseException e) {
                Toast.makeText(MainActivity.this, "验证失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            }

            // 验证码发送成功,拿到verificationId
            @Override
            public void onCodeSent(String verificationId,
                                   PhoneAuthProvider.ForceResendingToken token) {
                // 保存verificationId,等用户输入验证码后使用
                mVerificationId = verificationId;
                mResendToken = token;
                Toast.makeText(MainActivity.this, "验证码已发送", Toast.LENGTH_SHORT).show();
            }
        });

手动输入验证码后的验证代码

// 用户点击验证按钮时调用
public void onVerifyCodeClick(View view) {
    String userInputCode = etVerificationCode.getText().toString().trim();
    if (TextUtils.isEmpty(userInputCode)) {
        Toast.makeText(this, "请输入验证码", Toast.LENGTH_SHORT).show();
        return;
    }
    if (TextUtils.isEmpty(mVerificationId)) {
        Toast.makeText(this, "请先获取验证码", Toast.LENGTH_SHORT).show();
        return;
    }
    // 创建凭证
    PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, userInputCode);
    // 登录
    signInWithPhoneAuthCredential(credential);
}

// 登录方法
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    FirebaseAuth.getInstance().signInWithCredential(credential)
            .addOnCompleteListener(this, task -> {
                if (task.isSuccessful()) {
                    // 登录成功,处理逻辑
                    FirebaseUser user = task.getResult().getUser();
                    Toast.makeText(MainActivity.this, "登录成功:" + user.getPhoneNumber(), Toast.LENGTH_SHORT).show();
                } else {
                    // 登录失败,处理错误
                    if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                        Toast.makeText(MainActivity.this, "验证码错误", Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

保存verificationId避免配置更改丢失

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    // 保存verificationId
    outState.putString("VERIFICATION_ID", mVerificationId);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // 恢复verificationId
    mVerificationId = savedInstanceState.getString("VERIFICATION_ID");
}

按照这个流程调整你的代码,应该就能解决这个崩溃问题啦!

内容的提问来源于stack exchange,提问作者Yara El Ashram

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:02:04