如何使用FirebaseMessagingService在后台获取推送通知数据?

4
我正在使用 FirebaseMessagingService 处理推送通知。在应用中,它能够正常工作。当调用 onMessageReceived 时,我可以获取通知标题和正文以及数据负载,并根据负载数据向我的 Activity 发送反应,使用 LocalBroadcastManager

但是,后台推送通知存在问题。这只会在后台显示通知,但如果应用程序在后台,则不会在 onMessageReceived 中创建此函数,因为无法调用此函数。

根据文档,推送通知的数据部分存储在 extras 中,并且可以在 Activity 恢复时找到。我已经有了这个功能并且它可以工作。但问题是我没有标题和消息,因为它没有发送到 onMessageReceived,我无法捕获此信息。

是否有任何方法可以获取它?因为我需要在应用程序内的对话框窗口中显示它。推送通知不仅是文本和标题,而且不仅仅是用户的信息,而且还将执行某些操作。

FirebaseMessagingService 中接收通知标题、正文和负载:

override fun onMessageReceived(msg: RemoteMessage?) {
        val pNotification = msg?.notification
        val payload = msg?.data
        if (pNotification != null){
            val ntitle = pNotification.title
            val nMsg = pNotification.body
        }
        //working with payload - creating notification and Intent for LocalBroadcastmanager
}

onResume()中获取extras中的有效载荷。
private fun maybeFindBackgroundPayload(extras: Bundle?){
        if (extras != null){
            extras.keySet().forEach { key->
                val keyValue = extras[key]
                App.log("BackgroundKeyValues: $keyValue")
                if (key.equals("gcm.notification.body", ignoreCase = true) && keyValue != null){
                    ...
                    //Working with payload data key value - dont have title and body
                }
            }
        }
    }

1
不可能通过Firebase实现,因为当应用程序在后台时,Firebase会处理收到的通知并将其显示出来,用户需要点击通知,然后才能传递数据给您的应用程序。 - Sudarshan Vidhate
我认为你应该在数据负载中传递相同的信息...通知标题和正文不存储在额外的参数中。 - Naitik Soni
你有没有找到解决这个问题的办法?因为我也遇到了同样的问题。我已经检查过,一些设备在收到消息时可以正常工作,但是如果用户手动滑动或从最近任务中清除我们的应用程序,有些设备是不允许的。 - Gulab Sagevadiya
2个回答

7
很遗憾,按照你的要求,它无法实现。
如果推送通知在有效负载中有通知部分并且您的应用程序在后台运行,则 onMessageReceived 不会被调用。通知将由 Firebase 自动创建并显示。无法拦截此通知或修改通知,也不能执行其他任何操作。只有在用户点击通知后,您的应用程序才能获得控制权。
正如您所提到的,当应用程序在前台时,onMessageReceived 将始终被调用。
确保在所有情况下(前景、后台和应用程序已被杀死)都调用 onMessageReceived 的唯一方法是从 Firebase 发送仅数据的有效负载。也就是说,删除 Firebase 有效负载主体的通知部分,并将内容(标题、正文等)放入有效负载的数据部分。然后在您的 onMessageReceived 中将这些内容赋值给正在创建的通知。
以下是来自 Firebase 的有效负载需要的格式:
{
"registration_ids":[
  "firebase_token"
],
"data":{
    "body":"body of notification",
    "title":"title of notification",
    "otherdatakey":"otherdatavalue"
}
}

然后在你的 onMessageReceived 函数中,你需要显式地提取标题和正文,并将其分配给通知(当然还可以进行任何其他操作):

@Override
public void onMessageReceived(RemoteMessage message) {
Map<String, String> dataMap = message.getData();
String title = dataMap.get("title");
String body = dataMap.get("body");
String otherdatavalue = dataMap.get("otherdatakey");
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            .setContentTitle(title)
            .setContentText(body)
            .setContentIntent(pendingIntent);//To handle click of notification

}

是的,它可以工作,但不适用于每个操作系统,因为我有两台设备,一台是荣耀7X,可以在被杀死的状态下接收数据,另一台是OPPO F5,在被杀死的状态下无法接收数据。有没有解决这个问题的办法? - Gulab Sagevadiya

0

你尝试过从 public void handleIntent(Intent intent) 方法中获取通知和数据吗?对我来说它很完美地工作。我曾经尝试过只使用 onMessageReceived 来获取通知和/或数据,但一直遇到困难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接