【问题标题】:How to handle firebase notification on background as well as foreground?如何在后台和前台处理 Firebase 通知?
【发布时间】: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.
}

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

【问题讨论】:

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

标签: android firebase firebase-cloud-messaging


【解决方案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......",
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      • 2016-11-21
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多