FirebaseMessaging获取FCM token返回空值问题求助
FCM 空Token获取异常解决方案
三类异常根因说明
你上报的三类异常对应问题如下:
java.io.IOException: SERVICE_NOT_AVAILABLE:并非仅由Google Play服务未安装导致,更常见原因是设备网络无法访问FCM服务、Google Play服务被后台进程限制、本地服务缓存异常导致连接失败java.io.IOException: AUTHENTICATION_FAILED:核心是身份校验失败,常见原因包括设备上登录的Google账号凭证过期/状态异常、应用打包使用的签名、包名和Firebase控制台配置不匹配、google-services.json配置文件错误java.io.IOException: PHONE_REGISTRATION_ERROR:设备层面注册限制,常见原因包括Google Play服务版本过低不兼容当前Firebase SDK、设备系统为修改后的定制ROM、设备系统时间和标准时间偏差过大导致签名校验失败
可落地解决方案
1. 增加Token获取重试机制
单次调用getToken失败概率较高,建议增加指数退避重试逻辑,避免偶发网络、服务波动导致的获取失败:
import kotlin.math.pow private fun retryFetchFCMToken(retryTimes: Int = 0) { val maxRetryCount = 5 if (retryTimes >= maxRetryCount) { // 重试达到上限,走兜底推送逻辑 return } FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> if (task.isSuccessful && !task.result.isNullOrEmpty()) { // 正常获取到Token,执行业务逻辑 return@addOnCompleteListener } // 异常场景延迟重试,重试间隔随次数指数增长 val delayMs = (1000 * (2.0.pow(retryTimes))).toLong() Handler(Looper.getMainLooper()).postDelayed({ retryFetchFCMToken(retryTimes + 1) }, delayMs) } }
2. 完善Google Play服务校验逻辑
makeGooglePlayServicesAvailable仅能处理部分可恢复的服务异常,建议先做状态前置校验,可恢复的异常引导用户手动处理:
val googleApi = GoogleApiAvailability.getInstance() val serviceStatus = googleApi.isGooglePlayServicesAvailable(this) if (serviceStatus != ConnectionResult.SUCCESS) { if (googleApi.isUserResolvableError(serviceStatus)) { // 弹出系统弹窗引导用户更新/授权Google Play服务 googleApi.getErrorDialog(this, serviceStatus, 1001)?.show() } else { // 设备不支持Google服务,直接走兜底方案 } }
3. 排查配置兼容问题
- 确认应用包名、打包签名、
google-services.json文件和Firebase控制台的项目配置完全一致 - 将Firebase Messaging SDK升级到最新稳定版,规避旧版本已知的Token获取缺陷
- 增加系统时间校验,如果设备时间和标准时间偏差超过1小时,提示用户校准时间,避免签名校验失败
- 若你的应用有国内用户,需明确告知需在可访问Google服务的网络环境下使用FCM,同时接入国内厂商推送通道(小米、华为、OPPO、VIVO等)作为兜底
4. 极端场景兜底
如果多次重试后仍无法获取Token,不要阻塞业务流程,直接切换到自有推送通道或其他第三方推送服务,保证推送能力可用。
内容的提问来源于stack exchange,提问作者ihsanhf
相关产品推荐
相关产品推荐

