Android端Firebase OTP自动验证更新SDK后回调无法触发问题
Firebase手机号OTP自动验证新版本失效问题解决办法
问题场景
使用com.google.firebase:firebase-auth:19.3.1时,手机号OTP自动验证功能正常,onVerificationCompleted回调能正常触发。但升级到com.google.firebase:firebase-auth:21.0.6或使用Firebase BOM版本com.google.firebase:firebase-bom:30.2.0后,自动验证流程失效,无法触发对应回调。
解决步骤
1. 补充必要权限配置
新版本Firebase Auth对自动读取OTP的权限要求更严格,需在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" />
针对Android 13及以上系统,还需动态申请READ_SMS权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityResultContracts.RequestPermission requestPermission = new ActivityResultContracts.RequestPermission(); registerForActivityResult(requestPermission, isGranted -> { if (isGranted) { // 权限已授予,执行验证流程 } else { Toast.makeText(this, "需要读取短信权限以完成自动验证", Toast.LENGTH_SHORT).show(); } }).launch(Manifest.permission.READ_SMS); }
2. 确保SmsRetriever配置正确
新版本Firebase自动验证依赖SmsRetriever API,需满足以下条件:
- 在Firebase控制台中,已正确配置应用的SHA-1和SHA-256签名指纹(项目设置 -> 应用 -> 添加指纹)。
- 确保Firebase发送的OTP短信包含应用的哈希字符串(格式示例:
FA+9qCX9VSu),该哈希由应用签名生成,可通过Firebase工具或代码获取。
3. 修复代码中的异步调用隐患
原代码中user.getIdToken(false).getResult().getToken()为同步调用,getIdToken是异步操作,会导致潜在异常,需改为异步处理:
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) { if (mAuth != null) { mAuth.signInWithCredential(credential).addOnCompleteListener(this, task -> { if (task.isSuccessful()) { FirebaseUser user = task.getResult().getUser(); if (user != null) { // 异步获取ID Token user.getIdToken(false) .addOnSuccessListener(getIdTokenResult -> { String token = getIdTokenResult.getToken(); if (token != null) { Log.e("Login", "Number Verified"); // SendToOTPScreen(token); } else { Toast.makeText(MainActivity.this, "Invalid Code", Toast.LENGTH_SHORT).show(); } }) .addOnFailureListener(e -> { Toast.makeText(MainActivity.this, "获取Token失败", Toast.LENGTH_SHORT).show(); }); } } }).addOnFailureListener(e -> { if (e instanceof FirebaseAuthInvalidCredentialsException) { Toast.makeText(MainActivity.this, "验证码无效", Toast.LENGTH_SHORT).show(); } }).addOnCanceledListener(() -> { Toast.makeText(MainActivity.this, "验证已取消", Toast.LENGTH_SHORT).show(); }); } }
4. 检查Activity生命周期与回调绑定
确保setActivity(this)传入的是当前活跃的Activity实例,避免因Activity销毁导致回调丢失。如果使用Fragment,可传入Fragment的宿主Activity或使用setFragment(this)(Firebase Auth新版本支持)。
内容的提问来源于stack exchange,提问作者Manoj Yadav
相关产品推荐
相关产品推荐

