繁体   English   中英

当我的应用程序前台服务被终止时,未收到 FCM 通知

[英]FCM Notification is not received when my app foreground service is killed

当我的应用程序前台服务被杀死时,没有收到 FCM 通知,更清楚地说,我试图让我的应用程序始终在后台运行,我使用前台服务来实现这一点,有时应用程序没有被 ANDROID 系统杀死,并且前台通知出现超过 15 小时,但有时它在 1 小时或更短时间或 2 小时或更短时间后终止,当我的前台通知被终止并且我发送 FCM 通知时它没有被我的设备接收! 这里有什么问题! 我该如何解决!

在前台处理通知

当应用程序关闭时,您的通知将由 Google 服务进程处理,该进程负责根据需要显示您的通知,包括默认点击操作(打开应用程序)和通知图标。

当应用程序在前台时,收到的消息由应用程序处理,由于没有逻辑来处理它,所以什么都不会发生!

为了解决这个问题,我们需要自己的FirebaseMessagingService ,让我们创建一个。 创建一个新的 class 扩展它并实现onMessageReceived方法。 然后从 remoteMessage 中获取 Notification remoteMessage并创建自己的 Android Notification。

public class NotificationService extends FirebaseMessagingService { 
  @Override
  public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    Notification notification = new NotificationCompat.Builder(this)
      .setContentTitle(remoteMessage.getNotification().getTitle())
      .setContentText(remoteMessage.getNotification().getBody())
      .setSmallIcon(R.mipmap.ic_launcher)
      .build();
     NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
     manager.notify(123, notification);
   }
}

然后在您的AndroidManifest.xml中添加服务

<service android:name=”.NotificationService”>
 <intent-filter>
  <action android:name=”com.google.firebase.MESSAGING_EVENT”/>
 </intent-filter>
</service>

现在,如果您再试一次,您将在应用处于前台时显示通知!

在现实生活中,您的onMessageReceived内容会稍微复杂一些,您将需要根据通知类型的不同智能操作,您将希望显示一个更好的大图标(出现在通知正文上的那个)并确保更改状态栏图标。

您现在遇到的问题是您的onMessageReceived仅在应用程序处于前台时调用,如果您的应用程序是后台,Google 服务将负责显示您的消息。

解决方案? 不要使用“通知”消息负载,而是使用“数据”。 使用数据

解决此前台/后台问题的最后一步是从消息负载中删除通知 object。

而不是发送:

{
   "to": "the device token"
   "notification":{
     "title":"New Notification!",
     "body":"Test"
   },
   "priority":10
 }

Send:

{
   "to": "the device token"
   "data":{
     "title":"New Notification!",
     "body":"Test"
   },
   "priority":10
 }

这样,您的通知将始终由应用程序、您的 NotificationService 处理,而不是由 Google 服务进程处理。

您还需要更改代码以处理数据负载:

// Old Way
//.setContentTitle(remoteMessage.getNotification().get(“title”))
//.setContentText(remoteMessage.getNotification().get(“body”))

// New Way
.setContentTitle(remoteMessage.getData().get(“title”))
.setContentText(remoteMessage.getData().get(“body”))

您的整个 NotificationService 现在将如下所示:

public class NotificationService extends FirebaseMessagingService { 
  @Override
  public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    Notification notification = new NotificationCompat.Builder(this)
      .setContentTitle(remoteMessage.getData().get(“title”))
      .setContentText(remoteMessage.getData().get(“body”))
      .setSmallIcon(R.mipmap.ic_launcher)
      .build();
     NotificationManagerCompat manager = NotificationManagerCompat.from(getApplicationContext());
     manager.notify(123, notification);
   }
}

使用数据而不是通知 object 的另一个优点是,您可以在“数据”object 中放入任何您想要的内容。 例如,用户 ID、URL 到图像……您可能想要用于构建通知或传递给点击操作的任何信息。 请注意,所有内容都将被视为字符串。 例如,

"data":{
     "title":"New Notification!",
     "body":"Test",
     "user_id": "1234",
     "avatar_url": "http://www.example.com/avatar.jpg"
 },

此差异也在本文档的“处理消息”部分中进行了说明: https://firebase.google.com/docs/cloud-messaging/android/receive

结论

请注意,如果您在有效负载中保留“通知” object,它将像以前一样运行。 您需要摆脱“通知”,只提供“数据”object。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM