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

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目