Android启动FirebaseMessagingService后立即调用getToken致首次令牌获取失败?
Firebase Messaging首次调用getToken失败、二次进入Activity成功的问题解决
问题现象
用户确认接收消息后,在Activity中手动启动myFirebaseMessagingService并立即调用getToken(),大量设备首次调用无法获取令牌,但第二次进入该Activity(服务已运行)时可成功获取。当前使用Firebase Messaging 22.0.0版本。
核心原因分析
你怀疑的启动服务后过早调用getToken是核心诱因:
startService()是异步操作,服务启动完成需要耗时,此时立即调用getToken(),Firebase Messaging的初始化流程可能尚未完成,导致令牌生成失败。- 调试环境设备性能较好,服务启动速度快,因此无法复现问题,但量产设备性能参差不齐,时序问题就会暴露。
- 第二次进入Activity时,服务已处于运行状态,Firebase Messaging初始化流程已完成,所以
getToken()能成功获取令牌。
解决方案
方案1:移除手动启动服务的逻辑,依赖Firebase自动初始化
Firebase Messaging本身会自动注册并启动服务,手动调用startService()完全多余,反而会打乱初始化时序。简化后的代码如下:
// 移除手动启动服务的代码 // Intent i = new Intent(this, myFirebaseMessagingService.class); // startService(i); // 若Application类中已完成Firebase初始化,这行也可移除 FirebaseApp.initializeApp(this); FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() { @Override public void onComplete(@NonNull Task<String> task) { if (task.isSuccessful()) { String token = task.getResult(); // send token to server... } else { // 处理获取失败的情况,比如添加重试逻辑 Log.e("FCM", "getToken failed", task.getException()); } } });
方案2:监听服务启动状态,完成后再调用getToken(不推荐,仅适用于必须手动启动服务的场景)
通过ServiceConnection监听服务连接状态,在服务启动完成后再调用getToken():
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 服务已启动,此时调用getToken FirebaseMessaging.getInstance().getToken().addOnCompleteListener(...); } @Override public void onServiceDisconnected(ComponentName name) { // 服务断开后的处理逻辑 } }; // 启动并绑定服务 Intent intent = new Intent(this, myFirebaseMessagingService.class); startService(intent); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
方案3:升级Firebase Messaging版本
Firebase Messaging 22.0.0属于较旧版本,旧版本存在部分初始化时序相关的bug,升级到最新稳定版(当前已到23.x系列)大概率能解决这类问题。升级时注意同步更新Firebase其他相关依赖,保持版本一致。
额外排查建议
- 检查
AndroidManifest.xml中Firebase Messaging服务的配置是否正确:<service android:name=".myFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> - 在
myFirebaseMessagingService的onCreate()方法中添加日志,确认服务是否正常启动:@Override public void onCreate() { super.onCreate(); Log.d("FCM Service", "Service created successfully"); } - 为
getToken()添加失败重试逻辑,避免用户首次操作完全失效。
内容的提问来源于stack exchange,提问作者ScottyB
相关产品推荐
相关产品推荐

