Jetpack Compose下通过SmsRetriever短信广播获取OTP失败抛出空指针异常
问题根因
SystemBroadcastReceiver实现错误:你将SmsRetriever.SEND_PERMISSION这个权限值错误当成广播 Action 注册了第二个无效的广播接收器,接收到非法广播 Intent 后触发了 Firebase Auth 内部的空指针异常- 注册广播接收器时没有传入对应的权限校验,导致第三方恶意广播也能触发你的接收器逻辑
- 代码中存在多处未做空安全校验的强转逻辑
- OTP提取函数没有做边界校验,短信内数字不足指定长度时会触发下标越界异常
修复方案
1. 重写 SystemBroadcastReceiver 函数
删除无效的第二个广播注册逻辑,注册时正确传入权限参数:
@Composable fun SystemBroadcastReceiver( systemAction: String, broadCastPermission: String, onSystemEvent: (intent: Intent?) -> Unit ) { val context = LocalContext.current val currentOnSystemEvent by rememberUpdatedState(onSystemEvent) DisposableEffect(context, systemAction, broadCastPermission) { val intentFilter = IntentFilter(systemAction) val broadcast = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { currentOnSystemEvent(intent) } } // 注册时正确传入权限参数 context.registerReceiver(broadcast, intentFilter, broadCastPermission, null) onDispose { context.unregisterReceiver(broadcast) } } }
2. 修复 SmsRetrieverUserConsentBroadcast 中的强转空安全问题
对 Status 提取逻辑增加空判断:
if (shouldRegisterReceiver) { SystemBroadcastReceiver( systemAction = SmsRetriever.SMS_RETRIEVED_ACTION, broadCastPermission = SmsRetriever.SEND_PERMISSION, ) { intent -> if (intent != null && SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) { val extras = intent.extras // 增加空判断避免强转空指针 val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as? Status ?: return@SystemBroadcastReceiver when (smsRetrieverStatus.statusCode) { CommonStatusCodes.SUCCESS -> { val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT) consentIntent?.let { try { launcher.launch(it) } catch (e: ActivityNotFoundException) { // 可添加异常上报逻辑 } } } CommonStatusCodes.TIMEOUT -> { shouldRegisterReceiver = false } } } } }
3. 修复 OTP 提取函数的边界校验
internal fun getVerificationCodeFromSms(sms: String, smsCodeLength: Int): String { val digits = sms.filter { it.isDigit() } return if (digits.length >= smsCodeLength) { digits.substring(0, smsCodeLength) } else { "" } }
额外校验项
- 检查应用是否已经申请了
android.permission.RECEIVE_SMS权限,Android 13及以上版本需要动态申请该权限 - 确认服务端发送的OTP短信格式符合Google SMS Retriever要求:长度不超过140字节,包含
<#>前缀和你的应用11位哈希后缀
内容的提问来源于stack exchange,提问作者Gautam Hazarika
相关产品推荐
相关产品推荐

