部分设备Firebase Device Token为空且OnTokenRefresh未触发
解决Android 4.4.2设备获取Firebase Device Token为null的问题
嘿,针对你遇到的部分4.4.2设备拿不到Firebase Device Token(其他设备正常)的问题,我整理了几个针对性的排查和解决步骤,都是实际项目中踩过坑后验证有效的方案:
一、先排查Firebase SDK版本兼容性
这是老设备最容易踩的坑!Firebase从BoM 32.0.0版本开始就不再支持API 19(也就是Android 4.4.2)了,如果你的项目用了较新的SDK版本,直接就会导致老设备无法初始化Firebase服务。
- 建议降级到支持API 19的版本,比如在Module级别的
build.gradle里配置:
这个版本是官方明确支持API 19的最后几个稳定版本之一。implementation platform('com.google.firebase:firebase-bom:31.5.0') implementation 'com.google.firebase:firebase-messaging'
二、检查设备上的Google Play Services版本
Firebase Token的获取完全依赖Google Play Services,4.4.2设备上的Google Play Services大概率版本过低,至少要保证版本在11.8.0及以上才能正常兼容。
- 你可以在代码里加个版本检查,引导用户更新:
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance(); int resultCode = apiAvailability.isGooglePlayServicesAvailable(context); if (resultCode != ConnectionResult.SUCCESS) { if (apiAvailability.isUserResolvableError(resultCode)) { // 弹出更新提示框 apiAvailability.getErrorDialog(activity, resultCode, 9000).show(); } else { // 这种情况就是设备太老,完全不支持了,只能提示用户 } }
三、补全Manifest的配置细节
你提到已经加了部分配置,但可能还有遗漏:
- 首先确保你的
FireBaseMsgService正确继承自FirebaseMessagingService,并且实现了onNewToken方法:public class FireBaseMsgService extends FirebaseMessagingService { @Override public void onNewToken(@NonNull String token) { super.onNewToken(token); // 在这里处理拿到的新Token } } - Manifest里的服务配置要完整,注意action的完整路径:
<service android:name=".Services.FireBaseMsgService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <!-- 针对旧版Firebase,还要加InstanceID服务,兼容4.4.2更稳妥 --> <service android:name=".Services.MyFirebaseInstanceIDService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
四、调整Token的获取时机
很多人会在Application的onCreate里直接拿Token,但此时Firebase可能还没初始化完成,尤其老设备初始化更慢,大概率会返回null。
- 建议在Activity的
onStart里调用,或者用异步回调的方式获取:FirebaseMessaging.getInstance().getToken() .addOnCompleteListener(new OnCompleteListener<String>() { @Override public void onComplete(@NonNull Task<String> task) { if (!task.isSuccessful()) { Log.w(TAG, "获取FCM Token失败", task.getException()); return; } // 成功拿到Token String token = task.getResult(); } });
五、解决TLS版本兼容问题
Android 4.4.2默认不支持TLS 1.2,但Firebase服务要求必须用TLS 1.2以上的协议通信,这也是很多老设备拿不到Token的核心原因之一。
- 在Application的
onCreate里添加这段代码,强制启用TLS 1.2:if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { try { ProviderInstaller.installIfNeeded(getApplicationContext()); SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(null, null, null); sslContext.createSSLEngine(); } catch (Exception e) { e.printStackTrace(); } } - 同时别忘了Manifest里加必要的网络权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
六、排查设备的定制ROM问题
有些4.4.2的定制ROM会阉割或修改Google服务的配置,导致无法正常连接Firebase。你可以找一台原生Android 4.4.2的设备测试一下,如果原生设备能正常拿到Token,那就是用户设备的ROM问题,只能建议用户更换设备或者刷原生ROM。
内容的提问来源于stack exchange,提问作者user2352752
相关产品推荐
相关产品推荐

