Android 12+(SDK31+)FCM认证失败无法获取Token问题问询
Android 12+ FCM Token获取报AUTHENTICATION_FAILED排查方案
问题表现
已完成FCM基础接入,Android 11及更低版本设备上Token获取、消息推送功能正常;targetSdk升级到33后,Android 12及以上设备调用如下代码获取Token时失败:
FirebaseMessaging.getInstance().token.addOnCompleteListener { // 回调抛出异常 }
抛出异常信息:java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: AUTHENTICATION_FAILED
现有配置中自定义FirebaseMessagingService、通知权限、基础依赖引入无明显语法错误。
按优先级排查修复
1. 校验签名指纹配置(90%同类问题根因)
Android 12强化了FCM认证环节的应用签名校验逻辑,低版本仅校验SHA-1指纹,Android 12+会同时校验SHA-256指纹,漏配就会直接触发认证失败,低版本不受影响:
- 分别提取当前构建使用的调试签名、发布签名文件的SHA-1和SHA-256值,全部录入Firebase控制台对应应用的配置项中
- 录入完成后重新下载最新的
google-services.json文件,替换项目模块目录下的旧配置文件 - 多构建变体、多渠道包如果使用不同签名,必须把所有变体对应的签名指纹全部录入,不要遗漏
2. 升级存在兼容Bug的FCM依赖版本
你当前使用的firebase-messaging:23.0.4版本存在已知的Android 12+认证兼容缺陷,该版本在targetSdk 31+环境下会错误构造认证请求参数,直接升级到修复后的稳定版本即可:
// app模块build.gradle dependencies节点替换原有FCM依赖 implementation 'com.google.firebase:firebase-messaging:23.3.1'
同步检查项目根目录build.gradle中的Google服务插件版本,升级到匹配的稳定版:
// 根build.gradle buildscript dependencies节点 classpath 'com.google.gms:google-services:4.3.15'
升级完成后执行./gradlew clean清理构建缓存,避免旧版本依赖残留。
3. 检查清单配置合规性
Android 12强制要求所有带intent-filter的组件必须显式声明exported属性,你当前配置中MainActivity和AppFirebaseMessagingService的exported配置符合要求,额外注意两点:
- 不要手动修改、覆盖FCM SDK自带的内部服务、广播接收器的配置项,依赖版本正确的前提下,构建时会自动合并符合系统要求的清单配置
- 不要自定义高优先级的广播接收器拦截
com.google.android.c2dm.intent.RECEIVE、com.google.firebase.INSTANCE_ID_EVENT等FCM专属系统动作,会阻断Token刷新流程
4. 排查设备与环境问题
- 确认测试设备上的Google Play服务已升级到最新正式版,FCM认证逻辑依赖设备端Google Play服务组件,版本过低会导致Android 12+上认证流程不兼容
- 检查网络环境,不要使用会拦截HTTPS证书的代理、VPN工具,此类工具会导致FCM认证握手失败;部分网络环境无法正常连通FCM服务,需要切换可正常访问Google服务的网络测试
- 如果使用模拟器测试,必须选择带Google Play服务的官方镜像,不要使用第三方精简镜像
验证方法
- 完成上述修改后,先卸载测试设备上已安装的旧版本应用(避免旧签名、旧缓存影响)
- 重新构建安装应用,首次启动后等待3-5秒再调用Token获取接口,不要在应用刚启动时立刻请求
- 注意Android 13+的
POST_NOTIFICATIONS运行时权限仅影响通知展示,不影响Token获取流程,不需要等用户授权该权限再请求Token
参考验证代码:
FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> if (!task.isSuccessful) { Log.e("FCM", "Token获取失败", task.exception) return@addOnCompleteListener } val token = task.result Log.d("FCM", "Token获取成功: $token") }
同时保留FirebaseMessagingService的onNewToken回调日志,Token自动刷新时会通过该回调返回新值。
内容的提问来源于stack exchange,提问作者S.Baltrukevich
相关产品推荐
相关产品推荐

