Android firebase消息推送集成 FCM消息处理

2024-05-27 01:28

本文主要是介绍Android firebase消息推送集成 FCM消息处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

FirebaseMessagingService 是 Firebase Cloud Messaging (FCM) 提供的一个服务,用于处理来自 Firebase 服务器的消息。它有几个关键的方法,你提到的 onMessageReceiveddoRemoteMessagehandleIntent 各有不同的用途。下面逐一解释这些方法的作用和用法:

1. onMessageReceived(RemoteMessage message)

当你的应用处于前台时,如果有消息到达,就会回调 onMessageReceived 方法。这里是处理接收到的消息的逻辑部分。

override fun onMessageReceived(message: RemoteMessage) {super.onMessageReceived(message)// 你可以根据消息(message)的内容来做相应的处理,// 比如展示通知,更新UI等。
}

2. doRemoteMessage()

FirebaseMessagingService 的官方文档中,并没有直接提及 doRemoteMessage 这个方法。它可能是某个特定项目或库中特有的方法,而不是 Firebase SDK 的一部分。如果它存在于你的代码或你使用的某个库中,可能需要查找特定的文档或源代码来了解其具体用途。

3. handleIntent(Intent intent)

handleIntent 方法在服务中处理意图(Intent)。它不是 FirebaseMessagingService 专有的方法,而是 Android Service 类的一部分,可能会在接收到 Intent 时被调用。然而,在处理 FCM 相关的任务中,你通常不需要直接覆写或调用 handleIntent 方法。FCM 服务通常会自动处理消息的接收和分发工作,包括将消息派发到 onMessageReceived 方法。

如果你需要在后台接收消息并触发一些行为,通常会使用 onMessageReceived 来实现逻辑,因为 FCM 为这种用例提供了足够的支持。

注意:如果你的应用在后台,Firebase 通常会自动处理消息。如果消息中包含了通知负载,系统可能会自动显示通知,而不会调用 onMessageReceived。如果想要确保后台消息也触发 onMessageReceived,需要在发送消息时仅使用数据负载(即不包含通知负载),并确保应用实现了适当的后台运行条件(例如,使用高版本的 targetSdkVersion,考虑到 Android 的后台执行限制等)。

总之,对于绝大多数使用 Firebase Cloud Messaging 的场景,你主要会与 onMessageReceived 方法打交道,对于特殊的或自定义的方法(如 doRemoteMessage),需要参考特定的文档或代码实现。

当你使用 Firebase Cloud Messaging (FCM) 发送消息时,消息可以包含两种类型的数据:

  1. 通知负载:当应用在前台运行时,通过 onMessageReceived 处理;当应用在后台或被杀死时,系统会自动处理。
  2. 数据负载:无论应用是在前台、后台还是被杀死,都会触发 onMessageReceived(需要特定格式的负载才会在后台触发)。

以下是如何在 FirebaseMessagingServiceonMessageReceived 方法中获取消息标题、消息体和任意附加的数据(如 deeplink)的一个示例:

完整的 FirebaseMessagingService 示例

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessageclass MyFirebaseMessagingService : FirebaseMessagingService() {override fun onMessageReceived(remoteMessage: RemoteMessage) {super.onMessageReceived(remoteMessage)// 获取消息标题和内容(消息负载)val title = remoteMessage.notification?.title ?: "Default Title"val messageBody = remoteMessage.notification?.body ?: "Default Message Body"// 获取数据(数据负载)val data = remoteMessage.dataval deeplink = data["deeplink"] // 假定有一个键为"deeplink"的数据// 展示通知sendNotification(title, messageBody, deeplink ?: "default_deeplink")}private fun sendNotification(title: String, messageBody: String, deeplink: String) {val channelId = "YOUR_CHANNEL_ID"createNotificationChannel()val builder = NotificationCompat.Builder(this, channelId).setSmallIcon(R.drawable.ic_launcher_foreground) // 更改为你的通知图标.setContentTitle(title).setContentText(messageBody).setPriority(NotificationCompat.PRIORITY_DEFAULT)with(NotificationManagerCompat.from(this)) {// notificationId 是定义通知的唯一 int 值notify(System.currentTimeMillis().toInt(), builder.build())}// 处理 deeplink 或是其他额外的逻辑...}// Android 8.0 及以上需要创建通知频道private fun createNotificationChannel() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val name = "Channel Name"val descriptionText = "Channel Description"val importance = NotificationManager.IMPORTANCE_DEFAULTval channel = NotificationChannel("YOUR_CHANNEL_ID", name, importance).apply {description = descriptionText}val notificationManager: NotificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagernotificationManager.createNotificationChannel(channel)}}
}

请注意,您需要修改 R.drawable.ic_launcher_foreground 到您实际的通知图标资源,同时 "YOUR_CHANNEL_ID" 应该替换为您应用中的实际通知频道 ID。

通过上述代码,当 FCM 消息到达时(无论应用在前台、后台还是被杀死),onMessageReceived 都将触发(前提是符合数据消息的接收条件),您可以获取消息中的标题、消息体和附加的数据(如 deeplink),然后根据这些信息展示一条自定义通知。

在使用 Firebase Cloud Messaging (FCM) 时,您的应用可以接收两种类型的消息:通知消息数据消息。处理这些消息的方式与应用的前台/后台状态有关,以及消息的类型。

onMessageReceived 方法

onMessageReceived 方法在以下情况下被调用:

  • 应用在前台时,不论消息类型。
  • 应用在后台或被杀死时,仅当消息是数据消息(或通知和数据的混合消息,在这种情况下,数据部分被送达)。

处理后台消息

当您的应用处于后台或被杀死状态时,如果是纯通知消息,FCM 会自动展示通知,无需编写额外的接收代码。此外,点击通知可以自动打开应用或启动指定的活动(Activity),您可以在消息中指定 click_action 字段来指定要启动的活动,并在该活动中处理深链接。

实现深链接的点击响应

为了在点击通知后执行消息中携带的深链接,您可以:

  1. 在发送的消息中,设定通知消息的 click_action 属性,并为其指定一个唯一的值。
  2. 在应用的 AndroidManifest.xml 中,给相应的活动(Activity)配置一个 Intent Filter,该 Intent Filter 捕捉上一步中定义的 click_action

例如,您的消息结构可能如下所示:

{"to" : "FCM_TOKEN","notification" : {"body" : "消息正文","title": "消息标题","click_action":"OPEN_ACTIVITY_1"},"data" : {"extra_info" : "some_extra_information","deep_link" : "yourapp://deeplink/path"}
}

然后,在 AndroidManifest.xml 中配置捕捉这个动作的活动:

<activityandroid:name=".YourActivity"><intent-filter><action android:name="OPEN_ACTIVITY_1" /><category android:name="android.intent.category.DEFAULT" /></intent-filter>
</activity>

YourActivity 中,您可以获取数据并处理深链接:

if (intent.extras != null) {val deepLink = intent.extras.getString("deep_link")// 根据 deepLink 进行导航或其他操作
}

注意

当您的应用在后台或被杀死时接收通知消息,并且您希望在用户点击通知时执行一些代码(如处理深链接)时,上述方法一般可以实现目的。但是,如果需要在应用在后台或被杀死时收到的数据消息也能展示通知,并在点击时执行相应深链接,您需要在 onMessageReceived 方法中手动构建并展示通知,并处理点击事件。这一点非常重要,因为在后台时,数据消息不会自动展示通知,必须手动实现。

综上,您不需要(也不应该)直接修改 handleIntent 方法来处理普通的 FCM 消息。相反,您应专注于根据消息的类型和应用的状态,合理地使用 onMessageReceived 并处理通知的创建与点击响应。

在 Android 中,如果你想在收到 Firebase Cloud Messaging (FCM) 消息后展示自定义样式的通知,你可以在 onMessageReceived 方法中创建并展示一个通知。这给了你完全的控制权,允许你自定义通知的外观和行为。

以下是创建并展示一个自定义样式通知的基本步骤:

步骤 1: 创建 Notification Channel(仅限 Android Oreo (API 26) 及以上版本)

为了确保通知在 Android Oreo 及以上版本中正常工作,你需要创建一个 Notification Channel。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val channelName = "YourChannelName"val channelDescription = "YourChannelDescription"val channelId = "YourChannelId"val importance = NotificationManager.IMPORTANCE_DEFAULTval channel = NotificationChannel(channelId, channelName, importance).apply {description = channelDescription}// 注册通道val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagernotificationManager.createNotificationChannel(channel)
}

步骤 2: 创建自定义样式的通知

你可以使用 NotificationCompat.Builder 并利用其提供的样式,如 BigTextStyle, InboxStyle, BigPictureStyle 等来定制通知的视觉样式。

val builder = NotificationCompat.Builder(this, channelId) // 使用创建的通道ID.setSmallIcon(R.drawable.ic_notification) // 设置小图标.setContentTitle("Example Title") // 设置通知标题.setContentText("Example Description") // 设置通知内容.setPriority(NotificationCompat.PRIORITY_DEFAULT) // 设置优先级// 添加自定义样式.setStyle(NotificationCompat.BigTextStyle().bigText("Here is a longer text!"))// 构建 PendingIntent 来处理点击事件(例如打开 Activity)
val intent = Intent(this, YourActivity::class.java).apply {flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)builder.setContentIntent(pendingIntent)
builder.setAutoCancel(true) // 点击通知后自动消失

这里,YourActivity::class.java 应该替换为你想要打开的 Activity 的实际类名。

步骤 3: 展示通知

最后,使用 NotificationManager 来展示你刚才创建的通知。不要忘记替换通知的 ID(notificationId),如果你想要展示多个通知,每个通知的 ID 都应该是独一无二的。

with(NotificationManagerCompat.from(this)) {// notificationId 是定义通知的唯一 int 值notify(notificationId, builder.build())
}

将以上步骤放在 onMessageReceived 方法内,这样每当你的应用接收到 FCM 消息时,都会展示一个定制化的通知。如果消息带有数据负载,你还可以根据这些数据来定制通知的内容和样式。

请注意,如果用户已经关闭了你的应用的通知权限,或者当前设备上的系统设置禁止了通知,那么这些通知将不会展示。因此,确保在应用中妥善地处理通知权限请求和指导用户如何在系统设置中启用通知。

如果您在处理 Firebase Cloud Messaging (FCM) 消息时正确配置了,通常不会出现两条通知的情况。这里是出现冲突可能情况的一些分析和建议:

1. FCM 通知类型

FCM 允许发送两种类型的消息:

  • 通知消息:当应用在后台时,消息会自动被 FCM 处理,显示为系统通知。如果应用在前台,onMessageReceived 会被调用,您有机会处理这个通知。
  • 数据消息:无论应用处于前台还是后台,onMessageReceived 都会被调用,您需要自己编写代码来生成并显示通知。

2. 消息处理

  • 当您的应用处于前台,并且收到了一个通知消息,您可以在 onMessageReceived 方法内自定义如何处理这个通知,包括展示自定义通知。
  • 当应用处于后台,并且收到了一个通知消息,系统会自动处理这个通知,展示一个系统通知。这种情况下,onMessageReceived 不会被调用。
  • 当应用处于前台或后台,并且收到了一个数据消息onMessageReceived 会被调用,您可以在其中处理数据并决定是否展示通知。

3. 避免冲突

如果您在前台手动处理并展示通知,同时您的消息是一个通知消息,可能会出现两个通知:一个是 FCM 自动创建的,一个是您自己创建的。为避免这种情况,有两种方法:

  • 使用数据消息:确保发送的是数据消息而非通知消息。这样,无论应用处于前台还是后台,onMessageReceived 都会被调用,而不会生成自动的系统通知,您可以在接收到消息时自由地处理并展示您自己的通知。
  • 合理设计通知显示逻辑:如果您需要发送通知消息(例如,确保后台应用也能接收),则可以在 onMessageReceived 里加入逻辑仅在应用处于前台时展示自定义通知。这样,当应用处于后台时,只有 FCM 生成的系统通知会被展示;当应用处于前台时,则根据您在 onMessageReceived 中的逻辑展示自定义通知。

总结

正确地选择和处理消息类型可以避免同时出现两条通知的问题。如果您完全控制通知的显示逻辑(尤其是选择数据消息),就可以按照自己的需求来设计通知的展示,而不会出现冲突。

重写 handleIntent(Intent intent) 方法来处理来自 Firebase Cloud Messaging (FCM) 的消息并不是官方推荐的方法,且很可能不解决您提出的问题。在 Firebase 的旧版本里,有些开发者通过重写 handleIntent 方法来在应用处于后台时截获和修改消息。然而,这种做法存在几个问题:

  1. 维护性和兼容性:直接重写基础服务的方法(如 handleIntent)可能导致在未来的库更新中出现兼容性问题。Firebase 和 Android 平台都在不断进化,直接依赖于这些内部实现的细节可能导致您的应用在未来某个时间点突然出现问题。

  2. 违背设计初衷:Firebase Messaging 设计的初衷是简化推送通知的处理。它区分了「通知消息」和「数据消息」,并为这两种类型的消息提供了不同的处理路径。通过恰当地使用这两种消息类型,您应该能够满足大部分的需求,而无需通过重写底层方法来实现特定的行为。

解决方案

如果您的目标是确保即使在应用处于后台或被杀死状态下也能按照自定义方式处理通知,您应该使用数据消息。发送数据消息而非通知消息,让您有机会在应用的 onMessageReceived 方法中捕获所有消息,并自定义如何处理这些消息和通知,无论应用处于前台还是后台。

当应用在后台或被杀死时收到数据消息,您可以在 onMessageReceived 方法中创建并显示自定义通知,这时可以使用 Android 的标准通知构建方法来自定义通知的展示。

确保在您的消息发送逻辑中,使用了数据消息。例如:

{"to": "device_token_or_topic","data": {"key1": "value1","key2": "value2",// 更多自定义的键值对}
}

在 Android 客户端,您的 FirebaseMessagingServiceonMessageReceived 方法将接收到这些消息,即使在应用被杀死的情况下也是如此:

override fun onMessageReceived(remoteMessage: RemoteMessage) {// Handle data payloadif (remoteMessage.data.isNotEmpty()) {val myData = remoteMessage.data["key1"] // 例子// 根据接收到的数据处理逻辑// 比如,生成自定义通知}
}

通过这种方式,您可以完全控制通知的生成和展示逻辑,而不需要依赖于 Firebase 自动处理通知的机制,这样就不会产生重复的通知,也避免了需要重写 handleIntent 方法的需求。

这篇关于Android firebase消息推送集成 FCM消息处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006137

相关文章

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

SpringBoot使用注解集成Redis缓存的示例代码

《SpringBoot使用注解集成Redis缓存的示例代码》:本文主要介绍在SpringBoot中使用注解集成Redis缓存的步骤,包括添加依赖、创建相关配置类、需要缓存数据的类(Tes... 目录一、创建 Caching 配置类二、创建需要缓存数据的类三、测试方法Spring Boot 熟悉后,集成一个外

Docker集成CI/CD的项目实践

《Docker集成CI/CD的项目实践》本文主要介绍了Docker集成CI/CD的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、引言1.1 什么是 CI/CD?1.2 docker 在 CI/CD 中的作用二、Docke