1

我使用 Firebase Cloud Messaging (FCM) HTTP Legacy API 协议以 JSON 格式将推送通知发送到android 移动设备。对于客户端,我使用 react-native-fcm 库。目的是在应用程序处于 3 种状态时向特定设备发送通知:1) 运行 2) 后台运行 3) 已终止 根据 FCM 的文档,可以通过 FCM 服务发送 3 种不同类型的消息: 1)通知(具有预定义的字段)2)数据(设置您想要的任何字段)3)混合(通知+数据)。使用 react-native-fcm 在客户端监听传入消息事件的逻辑如下:

this.notificationEmitterSubscription = FCM.on(FCMEvent.Notification, notif => {
      if(notif && notif.fcm){
        //received from Firebase
        if(!notif.local_notification && notif.title){
          let badge = parseInt(notif.badge);
          FCM.setBadgeNumber(badge);
          this.showNotification(notif.title, notif.body, badge);
        }
        //notification is clicked
        if(notif.opened_from_tray){
          FCM.setBadgeNumber(0);
          this.executeNavigateAction(notif.fcm.action); //this method just navigates user to a particular screen in the application
        }
      }
    });

显示通知方法是这样实现的:

showNotification(title, body, badge) {
    FCM.presentLocalNotification({
      body: body,
      priority: "high",
      title: title,
      sound: "default", 
      large_icon: "ic_launcher",// Android only
      icon: "ic_launcher",
      show_in_foreground :true, /* notification when app is in foreground (local & remote)*/
      vibrate: 300, /* Android only default: 300, no vibration if you pass null*/
      lights: true, // Android only, LED blinking (default false)
      badge: badge,
      local: true,
      click_action: NAV_SCREEN_NAME
    });
  }

notif.title、notif.body 和 notif.badge 是通过 FCM API 发送消息时在数据部分设置的字段。换句话说,消息以 (3) 混合形式发送:

{
   "registration_ids" : ["FCM_device_token_1", "FCM_device_token_2"],
   "notification" :
   {
      "title" : "fcm notification message title",
      "body" : "fcm notification message body",
      "badge" : 111
   },
   "data" :
   {
      "title" : "fcm data message title",
      "body" : "fcm data message body",
      "badge" : 222
   }
}

如果消息作为(1) 通知发送(消息中没有“数据”部分,在这种情况下,需要对读取字段进行一些更改,以更改 notif.title -> notif.fcm.title,但这不是问题中的要点)或混合(3)然后当应用程序(2)后台运行和(3)被杀死时不会触发通知的侦听器。结果,没有设置徽章编号。但是尽管未调用方法 showNotification(title, body, badge) (因为未触发事件侦听器),但仍显示消息. 似乎 react-native-fcm 具有针对这种情况的内部实现,可以在应用程序未运行时自动显示 (1) 通知和 (3) 混合消息。换句话说,仅当应用程序 (1) 正在运行并且当应用程序处于 (2) 后台或 (3) 被杀死并且不显示徽章编号。但是,消息本身会针对所有情况显示。

另一种方法是发送(2) 数据消息。这种类型的 FCM 消息会触发应用程序所有状态的侦听器(notificationEmitterSubscription) :(1) running 和 (2) background running 和 (3)killed。结果,在所有这些状态中都设置了徽章编号。然而,尽管每当接收到数据 FCM 消息时都会调用方法 showNotification(title, body, badge) ,但如果应用程序被终止,方法 FCM.presentLocalNotification 不会显示该消息

因此,简而言之,我有一个问题。

如何:在 (1) 通知或 (3) 收到混合消息并且应用程序处于 (2) 后台运行或 (3) 被终止时显示徽章编号或在应用程序处于 (3) 时显示 (2) 数据消息) 被杀?

谢谢!

4

1 回答 1

0

已找到解决方案。声明是:如果应用程序被杀死,则没有代码在运行,因此消息将在您的代码中处理和显示。消息必须设置为下一种格式,以显示被杀死状态:

{
   "registration_ids" : ["FCM_token_1", "FCM_token_2"],
   "data" : 
   {
      "custom_notification" :
      {
         "title" : "FCM test title",
         "body" : "FCM test body"
      },
      badge : 1
   }
}

在通知处理程序中的 react-native 应用程序中,通知作为 notif.custom_notification 属性的 json 值接收。因此,代码如下所示:

this.notificationEmitterSubscription = FCM.on(FCMEvent.Notification, notif => {
      if(notif && notif.fcm){
        //received from Firebase
        if(!notif.local_notification && notif.custom_notification){
          let message = JSON.parse(notif.custom_notification);
          let body = message.body;
          let title = message.title;
          let badge = parseInt(notif.badge);
          FCM.setBadgeNumber(badge);
          this.showNotification(title, body, badge);
        }
        //notification is clicked
        if(notif.opened_from_tray){
          FCM.setBadgeNumber(0);
          this.executeNavigateAction(notif.fcm.action);
        }
      }
    });

该问题可以作为已解决的问题来解决。

于 2018-04-20T06:59:39.423 回答