Android 通知:数据和消息

Android Notification : Data & Message

我的 Android 通知(通过 FCM 发送)有问题。让我解释一下。

我可以发送显示在通知栏中的“经典”通知。我可以发送带有个性化数据的通知,但它们没有显示在通知栏中。

但是,我不能两者都做。目前,我发送的有效负载如下所示:

{
   "to":"token",
   "message":{
      "notification":{
         "body":"Body",
         "title":"Title"
      }
   },
   "data":{
      "id":2543,
      "type":"EVENT"
      "title":"Title"
      "body":"Body"
   }
}

确实发送了数据通知。但它不显示在 phone 上。 在我的服务中,我有我的 onMessageReceived 功能,其中包括:

val id = remoteMessage.data["id"]
val type = remoteMessage.data["type"]

只要我的通知进入数据模式,我就可以获得这些值。

所以,我认为显示通知和数据通知之间有一个我不理解的概念。

我用过这个link:https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

当我将 data 数组放入 message 时,通知没有到达。

如果你有线索,我很感兴趣。 基本思想是,当用户单击通知(其中包含事件的标题)时,应用程序会打开与事件的详细信息相匹配的 activity。

感谢您的帮助

[编辑] 这是我服务中的 onMessageReceived(remoteMessage: RemoteMessage) 函数,它扩展了 FirebaseMessagingService

override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        val intent:Intent?

        val id = remoteMessage.data["id"]
        val type = remoteMessage.data["type"]
        val title = remoteMessage.data["title"]
        val body = remoteMessage.data["body"]

        Log.i("YANN", "RemoteMessage Data : " + remoteMessage.data)
        Log.i("YANN", "Id : $id")
        Log.i("YANN", "Type : $type")
        Log.i("YANN", "Title : $title")
        Log.i("YANN", "Body : $body")

        when (type) {
            "NOTIFICATION" -> {
                // TODO : Load the NotificationFragment
                intent = Intent(this, MainActivity::class.java)
            }
            "POST" -> {
                var post:Post = Post(0, "", "", "", "", "")
                
                // DO SOMETHING TO RETRIVE THE POST
                intent = Intent(this, PostActivity::class.java)
                intent.putExtra("post", post)
            }
            "EVENT" -> {
                var event = Event(0, "", "", "", "", "", "", "")
                
                // DO SOMETHING TO RETRIEVE THE EVENT
                intent = Intent(this, EventActivity::class.java)
                intent.putExtra("event", event)
            }
            else ->  {
                intent = Intent(this, MainActivity::class.java)
            }
        }
        
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
        val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)

        val notification = NotificationCompat.Builder(this, resources.getString(R.string.default_notification_channel_id))
            .setSmallIcon(R.drawable.ic_dashboard_black_24dp)
            .setContentTitle(title)
            .setContentText(body)
            .setAutoCancel(true)
            .setSound(soundUri)
            .setContentIntent(pendingIntent)

        NotificationManagerCompat.from(this).notify(1, notification.build())
    }

[EDIT2] 有新的 NotificationBuilder

val builder: NotificationCompat.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val importance = NotificationManager.IMPORTANCE_DEFAULT
    val notificationChannel = NotificationChannel(resources.getString(R.string.default_notification_channel_id), resources.getString(R.string.default_notification_channel_id), importance)
    val notificationManager:NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    notificationManager.createNotificationChannel(notificationChannel)
    NotificationCompat.Builder(this, notificationChannel.id)
} else {
    NotificationCompat.Builder(this)
}

builder.setSmallIcon(R.drawable.ic_dashboard_black_24dp)
builder.setContentTitle(title)
builder.setContentText(body)
builder.setAutoCancel(true)
builder.setSound(soundUri)
builder.setContentIntent(pendingIntent)


val notificationID = (0..999999999).random()
NotificationManagerCompat.from(this).notify(notificationID, builder.build())

处理 Android 上的推送通知确实有点痛苦。解决问题的最简单方法是自己创建通知。

您代码中的某处必须有一个服务 class 扩展您在 AndroidManifest.xml 中声明的 FirebaseMessagingService。它有一个 onMessageReceived(message: RemoteMessage) 方法。

您可以这样获取消息内容

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)

        val remoteNotification = message.notification ?: return
        val title : String = remoteNotification.title
        val body : String = remoteNotification.body

然后你只需要通过创建通知来显示它,你可以在这里找到更多关于创建通知的信息:

https://developer.android.com/training/notify-user/build-notification

编辑: 在来自 Oreo 的 Android 的最新版本中,您需要指定您所做的频道。但是你忘了创建频道。 还要确保您支持 Android 的旧版本。像这样:


var builder: NotificationCompat.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val notificationChannel = NotificationChannel("mainChannelId", "Main", importance)
            notificationManager.createNotificationChannel(notificationChannel)
            NotificationCompat.Builder(applicationContext, notificationChannel.id)
        } else {
            NotificationCompat.Builder(applicationContext)
        }