如何在后台和前台处理 Firebase 通知?

Posted

技术标签:

【中文标题】如何在后台和前台处理 Firebase 通知?【英文标题】:How to handle firebase notification on background as well as foreground? 【发布时间】:2017-03-16 07:19:09 【问题描述】:

我想在后台和前台处理 firebase 通知消息。我将发送一条消息,其中包含来自开发人员的 youtube 链接,当用户点击通知栏时,它必须引导用户打开链接。有谁知道它是怎么做的吗?

 public void onMessageReceived(RemoteMessage remoteMessage) 
    // [START_EXCLUDE]
    // There are two types of messages data messages and notification messages. Data messages are handled
    // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
    // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
    // is in the foreground. When the app is in the background an automatically generated notification is displayed.
    // When the user taps on the notification they are returned to the app. Messages containing both notification
    // and data payloads are treated as notification messages. The Firebase console always sends notification

    // [END_EXCLUDE]

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be:
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) 
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
    

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) 
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.

接下来要做什么来实现我的目标?在此先感谢:)

【问题讨论】:

发布的代码只是示例中的代码。所以我假设你已经通过了它们。有什么令人困惑的地方吗?你也浏览过文档吗?现在,这就像一个给我代码问题。 试试我的解决方案?我已经试过了。它有效***.com/questions/48897883/… 【参考方案1】:

您应该在 FCM 消息中发送数据负载。无论您的应用程序处于前台还是后台,都会在消息方法中接收数据有效负载。处理那里的动作。比如通过始终读取数据负载来显示通知,或者如果您想在应用打开或在前台显示警报对话框。

这是一个示例负载:


  "to": "registration_id_or_topic",
  "data": 
        "message": "This is a Firebase Cloud Messaging Topic Message!",
        "youtubeURL": "https://youtu.be/A1SDBIViRtE"
   

然后在你的 onMessageReceived 中:

public void onMessageReceived(RemoteMessage remoteMessage) 
   if (remoteMessage.getData().size() > 0) 
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        Map<String, String> receivedMap = remoteMessage.getData();
        String youtubeURL = receivedMap.get("youtubeURL");
        showNotificationWithURLAction(youtubeURL);
   
   .....

您可以通过谷歌搜索轻松实现 showNotificationWithURLAction(...) 方法。一个样本是here

【讨论】:

如何在有效载荷中发送链接以及如何在用户点击时处理该链接?请帮帮我 请参阅下面@Lindani Masinga 的答案。我也会更新我的答案 要从控制台发送数据有效载荷,请参阅@Drake29a 的以下答案【参考方案2】:

这可能与this question 重复。不要在推送消息正文中发送“通知”。

所以基本上,我将推送通知请求的正文从:


   "data": 
       "type" : "mytype"
    ,
    "notification": 
        "title": "My Title",
        "body": "My Notification Message"
    ,
    "to": "/topics/all"

收件人:


   "data": 
       "type" : "mytype",
       "title": "My Title",
       "body": "My Notification Message"
    ,
    "to": "/topics/all"

现在我的应用即使在后台也每次都会调用 onMessageReceived(),我只是更改了方法以在推送数据中使用获得的通知标题和消息。

【讨论】:

嗨,我的应用没有在后台调用 onMessageReceived()。 谢谢!这是最重要和可接受的信息。从 8 小时开始,我一直在不停地挣扎,终于!正如你所说..它在两种情况下都有效 Alvin,后台应用程序是什么意思,我们应该在应用程序被杀死时收到通知,不仅在后台或前台。 @SagarPanwala 在后台,我的意思是当应用程序当前对用户不可见时 正是 Alvin,但我们都需要在应用被终止时收到通知【参考方案3】:

当您的应用终止或后台从不触发 onMessageReceive

你该怎么办?

当推送发送时只添加下面示例中的数据项; 你可以使用邮递员

首先需要这个网址:https://fcm.googleapis.com/fcm/send 发送时可以选择 发布

在你应该添加这样的标题之后:

内容类型:application/json

授权:key="你的服务器密钥"

  
        "to": "/topics/yourTopics",


        "data": 
            "title": "BlaBla",
            "body":"BlaBla"
         
    

如何处理;

class PushService : FirebaseMessagingService() 

     override fun onMessageReceived(remoteMessage: RemoteMessage?) 
    for (i in remoteMessage!!.data.keys) 
    //Your maps here you can do something..
    


        val contentIntent = PendingIntent.getActivity(this,
                0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
// Your notification set here!! 
        val b = NotificationCompat.Builder(this, "1")
        val n = b.setTicker(remoteMessage!!.data["title"])
                .setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(remoteMessage.data["title"])
                .setContentText(remoteMessage.data["body"])
                .setShowWhen(true)
                .setContentIntent(contentIntent)
                .setSound(uri)
                .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))
                .setStyle(NotificationCompat.BigTextStyle().bigText(remoteMessage.data["body"]))


        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
            b.setSmallIcon(R.drawable.ic_push_notification_transparent)
            b.color = ContextCompat.getColor(this, R.color.colorAccent)
         else 
            b.setSmallIcon(R.mipmap.ic_launcher)
        

        val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
            val channel = NotificationChannel("1",
                    "ic_notification",
                    NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
        

        if (notificationManager != null) 
            notificationManager.cancel(1)
            notificationManager.notify(1, n.build())
        
    



【讨论】:

【参考方案4】:

android 系统将始终处理有效负载中通知字段内的消息。如果您希望您的应用处理通知,则需要将 YouTube 链接放在有效负载的该数据字段中。

 "data" : 
     "link" : "www.youtube.com"

此通知在应用程序上作为 RemoteMessage 接收。使用 remoteMessage.getData() 获取 youtube 链接。

见https://firebase.google.com/docs/cloud-messaging/concept-options#messages-with-both-notification-and-data-payloads

【讨论】:

嗨,我的应用没有在后台调用 onMessageReceived()。【参考方案5】:

如果您想将用户重定向到应用中的内容而不是使用 deepLink, 以下是点击通知时如何打开链接:

Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
        notificationIntent.setData(Uri.parse(remoteMessage.getData().getString("url")); 
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
         // Resources r = getResources();
          Notification notification = new NotificationCompat.Builder(context)
                  .setTicker("yortext")
                  .setSmallIcon(android.R.drawable.ic_menu_report_image)
                  .setContentTitle("title")
                  .setContentText("content")
                  .setContentIntent(pendingIntent)
                  .build();

          NotificationManager notificationManager =  (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
          notificationManager.notify(0, notification);

要将有效负载发送到 Firebase 控制台,创建新消息,在这里您将拥有高级选项,您可以在其中将数据放在键/值对中,放入 网址如下图所示。

【讨论】:

Drake 在 fb 上接受我的好友请求我想对 firebase @Drake29a 提出更多疑问 在这里提问,fb 上没有好友请求。【参考方案6】:

这是一个用 nodejs 编写的适用于所有类型条件处理的工作示例 ForegroundBackGroundAPP Killed 这将适用于所有三种情况类型

let message = 
        "data": 
            "callerName": "callerName",
            "notifyType": "notifyType",
            "channelName": "channelName",
            "tragetuid": "tragetuid",
            "msg": "msg"
        ,

        token: "cq4KgPelQ_ukmAL1NmNs0l:APA91bG0l2uS1djSsD181cgtgFSd8......",
    ;

    let response = await admin.messaging().send(message).catch((error) => 
        console.log('Error sending message:', error);
    );
    if (!response) 
        ctx.status = 404;
        ctx.body = "Error";
     else 
        ctx.status = 200;
        ctx.body = 
            response, message
        ;
    

所以基本上我们需要使用类型 data 而不是 notification 在 OnReceived() 函数中获取 FCM 消息


        "data": 
            "callerName": "callerName",
            "notifyType": "notifyType",
            "channelName": "channelName",
            "tragetuid": "tragetuid",
            "msg": "msg"
        ,

        token: "cq4KgPelQ_ukmAL1NmNs0l:APA91bG0l2uS1djSsD181cgtgFSd8......",
    

【讨论】:

以上是关于如何在后台和前台处理 Firebase 通知?的主要内容,如果未能解决你的问题,请参考以下文章

android在后台处理大图片firebase通知

如何在应用程序后台接收FCM推送通知数据,但在前台点击

Flutter Firebase前台推送通知未显示但后台正在运行

Firebase 云消息传递前台通知在 Vue 中不起作用

如何使用 Firebase Cloud Messaging 在前台显示多个通知

当app在前台时发送推送通知