FirebaseInstanceIdService替代方案及自定义FCM服务配置正确性咨询
嘿,很高兴能帮你解决这个FCM的问题,我先给你明确替代方案,再仔细检查你的代码配置~
FirebaseInstanceIdService与onTokenRefresh的替代方案
Google已经正式弃用了FirebaseInstanceIdService及其onTokenRefresh方法,官方唯一推荐的替代方案就是继承FirebaseMessagingService并重写OnNewToken方法。这个方法会在FCM令牌首次生成或者后续刷新时被系统调用,完全覆盖了原来onTokenRefresh的功能。
你的代码配置检查与修正建议
先直接说核心问题:你现在写了两个继承自FirebaseMessagingService的类,并且都注册了相同的com.google.firebase.MESSAGING_EVENT IntentFilter,这会导致系统无法确定该调用哪个服务来处理FCM事件,必然出现冲突,这是需要修正的关键问题。
现有代码的问题细节
MyFirebaseIIDService:
- 继承
FirebaseMessagingService是正确的,OnNewToken里的逻辑(保存令牌、打印日志、注册到Notification Hub)也没问题,但没必要单独开一个类来处理令牌刷新。 - 重复注册
MESSAGING_EVENT过滤器会和另一个服务冲突。
- 继承
MyFirebaseMessagingService:
OnMessageReceived里区分通知payload和数据payload的逻辑是准确的(注释也很到位),但同样因为重复注册过滤器,会和第一个服务冲突。
修正后的合并代码
正确的做法是把令牌刷新和消息接收的逻辑合并到同一个FirebaseMessagingService子类中,这样就不会有冲突了:
[Service] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] class MyFirebaseMessagingService : FirebaseMessagingService { const string TAG = "MyFirebaseMsgService"; public const string NOTIFICATION_CHANNEL = "us.henrico.gov"; NotificationHub hub; // 替代原onTokenRefresh的令牌刷新处理 public override void OnNewToken(string refreshedToken) { base.OnNewToken(refreshedToken); Preferences.Set("notification_token", refreshedToken); Log.Debug(TAG, "FCM token: " + refreshedToken); SendRegistrationToServer(refreshedToken); } // 注册到Notification Hub的逻辑 void SendRegistrationToServer(string token) { hub = new NotificationHub(Parameter.NotificationHubName, Parameter.ListenConnectionString, this); var tags = GetEnabledCategories(); var regID = hub.Register(token, tags.ToArray()).RegistrationId; } // 处理FCM消息接收 public override void OnMessageReceived(RemoteMessage message) { if (message.GetNotification() != null) { // Notification payload:应用后台时由系统直接展示,不会触发此方法 SendNotification(message.GetNotification().Title, message.GetNotification().Body, message.Data["linktype"], message.Data["linkpage"]); } else { // Data payload:应用前台/后台都会触发此方法 SendNotification(message.Data["title"], message.Data["body"], message.Data["linktype"], message.Data["linkpage"]); } } // 请确保你有这个SendNotification的具体实现(这里补充占位) void SendNotification(string title, string body, string linkType, string linkPage) { // 你的通知创建与展示逻辑 } }
额外注意事项
- 如果你之前在
AndroidManifest.xml里手动注册过FirebaseInstanceIdService,请务必删除这部分配置,避免和新的服务冲突。 - 由于你使用了Xamarin的特性标签(
[Service]、[IntentFilter]),Firebase相关的服务配置会自动注入到Manifest中,不需要手动添加,这部分是没问题的。
内容的提问来源于stack exchange,提问作者Nantourakis
相关产品推荐
相关产品推荐

