Android SDK30/Gradle7无法获取FCM令牌、onNewToken未触发咨询
问题定位与修复方案
问题现状
- 开发环境:Android Studio compileSdk 30、Gradle 7
- 可正常接收推送通知,但无法获取设备FCM令牌
- 说明:能正常收推送不代表token拉取流程正常,推送通道依赖系统谷歌服务的长连接,和App端自身的FCM初始化、token拉取是独立运行的两条链路
- 现有参考方案的问题:网络上的相关说明多提及旧版
FirebaseInstanceId.getInstance()接口已废弃,剩余的实现仍在使用该废弃接口,当前环境无法正常调用
已完成的配置项
- AndroidManifest.xml 已配置Messaging服务:
<service android:name=".MyFirebaseMessagingService" android:exported="false" android:stopWithTask="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service>
- 根目录build.gradle已配置Google服务插件类路径:
classpath 'com.google.gms:google-services:4.3.5'
- 模块级build.gradle依赖配置:
dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.google.firebase:firebase-messaging:21.0.1' implementation 'com.google.firebase:firebase-core:18.0.2' implementation 'com.google.firebase:firebase-analytics' implementation platform('com.google.firebase:firebase-bom:26.5.0') testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' } apply plugin: 'com.google.gms.google-services'
- 自定义服务实现:
- 类
MyFirebaseMessagingService继承自FirebaseMessagingService - 已重写
onNewToken方法:
- 类
@Override public void onNewToken(@NonNull String token) { super.onNewToken(token); Log.e("newToken", token); getSharedPreferences("_", MODE_PRIVATE).edit().putString("fcm_token", token).apply(); }
异常表现
onNewToken方法从未触发,Logcat无newToken相关日志,无法获取有效设备令牌。
具体修复步骤
- 修正依赖配置冲突
当前配置同时手动指定了firebase-messaging、firebase-core的固定版本,又引入了Firebase BOM做版本统一管理,会造成依赖解析不一致:- 移除手动写死的
com.google.firebase:firebase-messaging:21.0.1、com.google.firebase:firebase-core:18.0.2行,BOM 26.5.0会自动匹配兼容的对应版本,无需手动声明 - 手动重复指定版本会打破BOM的统一版本约束,可能导致Messaging模块初始化异常
- 移除手动写死的
- 主动调用接口获取token,不要仅依赖onNewToken回调
onNewToken仅在App首次安装、token主动失效、用户清除App数据这三类场景下触发,如果手机之前已经安装过同包名App,本地已缓存旧token,该回调不会自动执行。需要在App启动流程中主动调用官方新接口拉取当前有效token:
该接口是替代废弃的FirebaseMessaging.getInstance().getToken() .addOnCompleteListener(task -> { if (!task.isSuccessful()) { Log.w("FCM", "拉取token失败", task.getException()); return; } String currentToken = task.getResult(); Log.d("FCM", "当前设备令牌: " + currentToken); // 拿到token后可直接存入本地SP getSharedPreferences("_", MODE_PRIVATE).edit().putString("fcm_token", currentToken).apply(); });FirebaseInstanceId的官方正式实现,当前依赖版本完全支持调用。 - 校验google-services.json配置有效性
- 确认文件已放置在模块根目录(和模块级build.gradle同级,而非项目根目录)
- 确认文件内登记的包名和App实际的applicationId完全一致,包名不匹配会导致服务初始化静默失败,无法触发token流程
- 检查基础权限配置
确认AndroidManifest中已声明android.permission.INTERNET、android.permission.ACCESS_NETWORK_STATE权限,缺失权限会导致FCM无法和服务端通信,拉取token流程会静默失败。
内容的提问来源于stack exchange,提问作者Jintor
相关产品推荐
相关产品推荐

