Android Firebase Phone Auth二次验证无法接收SMS问题求助
解决Firebase手机号验证后续无法接收短信的问题
我之前也碰到过一模一样的问题,结合你的描述和代码来看,问题核心在于Firebase Phone Auth的会话缓存和回调机制没有处理到位,下面给你拆解问题根源和具体的修复方案:
问题根源分析
- 未利用重发Token:当你重复请求验证码时,Firebase会默认复用之前的验证会话,不会重新发送短信——除非你传入
ForceResendingToken告诉它这是一个新的重发请求。 - 旧回调残留:你直接把Activity实例传给
verifyPhoneNumber,如果Activity被重建或者多次发起请求,旧的回调实例可能没有被清理,导致系统优先使用缓存的验证状态,而不是触发新的短信发送。 - 回调方法不完善:你的
onVerificationCompleted和onVerificationFailed是空实现,不仅会错过自动验证的场景,也无法在出错时重置会话状态。
代码修复步骤
1. 添加重发Token成员变量
在MainActivity类中新增一个成员变量,用于保存重发Token:
public class MainActivity extends AppCompatActivity { // ... 原有成员变量 private PhoneAuthProvider.ForceResendingToken mResendToken; // 新增这行 // ... 其他代码 }
2. 完善onCodeSent方法,保存重发Token
修改回调中的onCodeSent,把Firebase返回的Token保存下来:
@Override public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) { super.onCodeSent(s, forceResendingToken); codeSent = s; mResendToken = forceResendingToken; // 保存Token,用于后续重发请求 }
3. 修改sendVerificationCode方法,传入重发Token
在调用verifyPhoneNumber时,传入保存的Token,这样重复请求时Firebase会触发新的短信发送:
private void sendVerificationCode() { String phone = editTextPhone.getText().toString(); if (phone.isEmpty()) { editTextPhone.setError("Phone number is required"); editTextPhone.requestFocus(); return; } if (phone.length() < 6 || phone.length() > 13) { editTextPhone.setError("Please enter a valid phone"); editTextPhone.requestFocus(); return; } PhoneAuthProvider.getInstance().verifyPhoneNumber( phone, 60, TimeUnit.SECONDS, this, mCallbacks, mResendToken // 传入重发Token ); Toast.makeText(MainActivity.this, "SMS Sent, Please Wait....", Toast.LENGTH_LONG).show(); editTextCode.requestFocus(); }
4. 完善回调方法,处理自动验证和错误
补全onVerificationCompleted和onVerificationFailed的逻辑,让流程更健壮:
@Override public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) { // 系统自动读取短信完成验证,直接登录 signInWithPhoneAuthCredential(phoneAuthCredential); Toast.makeText(getApplicationContext(), "Auto-verified successfully!", Toast.LENGTH_SHORT).show(); } @Override public void onVerificationFailed(FirebaseException e) { Toast.makeText(getApplicationContext(), "Verification failed: " + e.getMessage(), Toast.LENGTH_LONG).show(); mResendToken = null; // 验证失败时重置Token,避免下次请求出错 }
5. 清理验证会话,避免旧回调残留
在Activity销毁时,取消当前的验证会话,防止旧回调干扰后续请求:
@Override protected void onDestroy() { super.onDestroy(); // 取消当前验证会话,清理旧回调 PhoneAuthProvider.getInstance().verifyPhoneNumber("", 0, TimeUnit.SECONDS, this, null); }
额外排查建议
- 去Firebase控制台的Authentication > Logs查看每次请求的状态,确认是否是Firebase侧拒绝发送短信。
- 测试时可以换不同的手机号,排除运营商对同一号码的短信频率限制。
- 确保你的
google-services.json是从Firebase控制台最新下载的,配置没有错误。
内容的提问来源于stack exchange,提问作者DragonFire
相关产品推荐
相关产品推荐

