576

这是我的舱单:

<service android:name=“.fcm.PshycoFirebaseMessagingServices”><意向过滤器><action android:name=“com.google.firebase.MESSAGING_EVENT”/></into-filter></服务><service android:name=“.fcm.PshycoFirebaseInstanceIDService”><意向过滤器><action android:name=“com.google.firebase.INSTANCE_ID_EVENT”/></into-filter></服务>

当应用程序处于后台并且收到通知时,默认通知会出现,并且不会运行我的代码收到消息时.

这是我的收到消息时代码。如果我的应用程序在前台运行,而不是在后台运行,则会调用此函数。当应用程序也处于后台时,我如何运行此代码?

//[开始接收消息]@覆盖public void onMessageReceived(远程消息远程消息){//TODO(开发人员):在此处处理FCM消息。//如果应用程序位于前台,请在此处处理数据和通知消息。//此外,如果您打算根据收到的FCM生成自己的通知//消息,这是应该启动的位置。请参阅下面的sendNotification方法。数据=remoteMessage.getData();字符串标题=remoteMessage.getNotification().getTitle();字符串消息=remoteMessage.getNotification().getBody();String imageUrl=(String)data.get(“image”);String action=(String)data.get(“action”);Log.i(标签,“onMessageReceived:title:”+标题);Log.i(TAG,“onMessageReceived:message:”+消息);Log.i(标签,“onMessageReceived:imageUrl:”+imageUll);Log.i(标签,“onMessageReceived:action:”+action);if(imageUrl==空){sendNotification(标题、消息、动作);}其他{新的BigPictureNotification(此、标题、消息、图像URL、操作);}}//[结束接收消息]
4
  • 它写在覆盖onMessageReceived()的示例,第二行评论说这里没有收到消息?看看为什么会这样:goo.gl/39bRNJ。解决方案与以下答案类似,可以在中的文档中找到包含通知和数据有效负载的消息
    – 布洛
    2017年1月22日23:19
  • 6
    简而言之,要唤醒被杀死的应用程序,您应该始终发送带有数据对象的通知,以调用应用程序中的通知服务类处理程序FirebaseMessagingService.onMessageReceived()。也可以尝试不从Firebase控制台发送,而是从其他地方发布(例如在线测试发布服务)。
    – 分区
    2017年7月13日9:41
  • 这个解决方案对我有效stackoverflow.com/a/44150822/6632278希望会有所帮助。祝你好运 2017年10月18日12:08
  • 您的清单中有什么“.fcm.”PshycoFirebaseMessagingServices?找不到类的错误。。在任何地方都找不到参数的第一部分是什么。 2020年5月23日22:59

31个答案31

重置为默认值
870
+50
答案推荐人谷歌云集体

1.为什么会发生这种情况?

FCM(Firebase云消息传递)中有两种类型的消息:

  1. 显示消息:这些消息触发收到消息时()仅当你的应用处于前景
  2. 数据消息:这些消息触发收到消息时()回调即使如果你的应用程序在前景/背景/终止

注:Firebase团队尚未开发要发送的UI数据消息你的设备。您应该使用服务器发送此类型!



2.如何操作?

要实现这一点,您必须执行邮政请求以下URL:

邮政 https://fcm.googleapis.com/fcm/send

标题

  • 密钥: 内容类型,数值: 应用程序/json
  • 密钥: 授权,数值: key=<您的服务器密钥>

车身使用主题

{“到”:“/topics/my_topic”,“数据”:{“my_custom_key”:“我的自定义值”,“my_custom_key2”:true}}

或者如果您想将其发送到特定设备

{“数据”:{“my_custom_key”:“我的自定义值”,“my_custom_key2”:真},“registration_ids”:[“{device-token}”,“{device 2-token}”}


注:确保你不添加JSON键通知
注:要获取服务器密钥,您可以在firebase控制台中找到它:您的项目->设置->项目设置->云消息->服务器密钥

3.如何处理推送通知消息?

这是您处理收到消息的方式:

@覆盖公共void onMessageReceived(RemoteMessage RemoteMessage){Map<String,String>data=remoteMessage.getData();字符串myCustomKey=data.get(“my_custom_key”);//管理数据}
24
  • 9
    您可以按照以下步骤在同一通知中发送“数据”和“通知”密钥stackoverflow.com/a/42279260/2734021:) 2017年2月23日21:38
  • 29
    Firebase团队还没有开发出向您的设备发送数据消息的UI。在过去的一年里,这种情况发生了变化吗? 2017年11月20日10:18
  • 114
    当应用程序处于后台时收到消息时没有接到电话,这是FCM中的一个严重问题!!!另外,请更新您的答案。 2018年4月4日7:39
  • 27
    三年后,这是仍然问题:如果你的应用程序在后台运行,onReceiveMessage将如果消息具有“通知”键,则调用它,而不管它是否具有“数据”键。由于服务器无法确定应用程序是否在后台运行,因此需要发送信息。荒谬的 2019年11月25日5:35
  • 12
    5年过去了,我们仍然无法处理背景FCM收到消息时也没有FCM控制台中的简单UI。这意味着需要更多的时间和后端工程师来为用户开发应用内通知中心和营销成员控制台等功能。为什么Firebase坚持不修复它? 2021年11月30日10:26
215

要使firebase库调用您的收到消息时()在下列情况下

  1. 前台应用程序
  2. 后台应用程序
  3. 应用程序已被终止

不能放置JSON键通知在您对Firebase API的请求中,但请使用数据,请参见下文。

以下消息不会呼叫您的收到消息时()当你的应用程序处于后台或被终止时,你无法自定义通知。

{“至”:“/topics/journal”,“通知”:{“title”:“标题”,“text”:“数据!”,“icon”:“ic_notification”}}

但相反,使用这个会奏效

{“至”:“/topics/dev_journal”,“数据”:{“text”:“文本”,“标题”:“”,“line1”:“日记”,“第2行”:“刊”}}

基本上,消息是在参数中发送的远程消息将数据对象作为映射<String,String>,然后可以在中管理通知收到消息时如这里的代码片段所示

@覆盖public void onMessageReceived(RemoteMessage RemoteMessage){Map<String,String>data=remoteMessage.getData();//你可以在这里得到你的短信。String text=data.get(“text”);通知Compat。Builder notificationBuilder=新建NotificationCompat。建筑商(本)//可选,这是为了制作漂亮的图标.setLargeIcon(位图工厂.decodeResource(getResources(),R.mipmap.ic_launcher)).setSmall图标(smallIcon)//必需......./*您可以在此处阅读有关通知的更多信息:https://developer.android.com/training/notify-user/build-notification.html网址:https://www.youtube.com/watch?v=-iog_fmm6米E*/}
16
  • 1
    是否可以从Firebase控制台实现这一点?
    – 科德
    2016年8月24日9:49
  • 1
    这就是我一天多以来一直在寻找的。。。。。非常感谢你,它运行得很好。如果你能解释一下如何在onMessageReceived()中处理数据中的键值对,从而用这些值启动活动,那会更好。 2016年11月24日8:42
  • 43
    当应用程序处于后台时,您的方法工作正常,但当应用程序被终止时,我不会接收数据
    – 桑扎尔
    2016年12月26日10:19
  • 12
    Sanzhar也有同样的问题。如果应用程序被终止,我不会收到任何消息。 2017年5月18日12:24
  • 1
    这在后台或被关闭时都有效,但如果你从设置中强制关闭你的应用程序,它将不起作用,但它确实很好,我认为这是最好的解决方案。 2018年10月28日19:47
160

我觉得所有的回复都是不完整的,但是当你的应用程序处于后台时,你需要处理一个包含数据的通知。

遵循这些步骤,您将能够在应用程序处于后台时处理通知。

  1. 添加意向滤波器这样地:

    <activity android:name=“.MainActivity”><意向过滤器><action android:name=“.MainActivity”/><category android:name=“android.intentation.category.DEFAULT”/></into-filter>

发送到要处理通知数据的活动。

  1. 使用以下格式发送通知:

    { “通知”:{“click_action”:“.MainActivity”,“body”:“新Symulti更新!”,“title”:“新Symulti更新!”,“图标”:“ic_notif_symulti”},“数据”:{…},“至”:“c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9”}

这里的关键是添加

“click_action”:“.MainActivity”

哪里.主要活动是具有意向过滤器您在步骤1中添加的。

  1. 获取数据onCreate中通知的信息.主要活动:

    protected void onCreate(捆绑保存的实例状态){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取通知数据信息捆绑包=getIntent().getExtras();if(bundle!=null){//捆绑包必须包含通知的“数据”字段中发送的所有信息}}

这应该就是你所需要做的。

15
  • 9
    这应该是正确的答案。所有的文档都没有提到需要click_action和Intent Filter才能让通知显示在托盘中。它们都是必需的。
    – 空运
    2017年2月21日22:17
  • @他们不需要通知就可以出现
    – 未定义
    2017年5月2日23:22
  • 1
    我有数据和通知块,但无法在活动中接收数据? 2017年9月5日13:24
  • 4
    我只是不明白为什么这不是公认的答案。如果没有click_action,它就无法工作。我今天过得很好 2018年11月1日4:07
  • 4
    感谢您在ArunShankar的支持。接受的答案比我的答案早了7个月,这是一个好答案。我不明白为什么没有人谈论click_action,这就是我添加答案的原因。我很高兴它对很多人都很有用,这是一天结束时最重要的:) 2018年11月1日13:57
60

根据中的firebase文档使用firebase向下游发送,有两种类型的有效载荷:

  1. 数据

    此参数指定消息有效负载的自定义键值对。客户端应用程序负责处理数据消息。数据消息只有自定义的键值对。

  2. 通知

    此参数指定通知负载的预定义、用户可见的键值对。FCM代表客户端应用程序自动向最终用户设备显示消息。通知消息具有一组预定义的用户可见密钥。

当您处于前台时,可以使用收到的消息(),您可以从中获取数据数据有效载荷。

数据=remoteMessage.getData();String customData=(String)data.get(“customData”);

当您在后台时,FCM将根据来自的信息在系统托盘中显示通知通知有效载荷。用于系统托盘上通知的标题、消息和图标可从通知有效载荷。

{“通知”:{“title”:“标题”,“body”:“正文”,“icon”:“ic_notification”,“click_action”:“OPEN_ACTIVITY_1”}}

这个通知当应用程序处于后台时,如果您希望在系统托盘上自动显示通知,则使用有效负载。要在应用程序处于后台时获取通知数据,您应该在其中添加click_action通知有效载荷。

如果您想打开应用程序并执行特定操作[在后台],请在通知负载中设置click_action,并将其映射到要启动的“活动”中的意图过滤器。例如,将click_action设置为OPEN_ACTIVITY_1以触发如下所示的意图过滤器:

<意向过滤器><action android:name=“OPEN_ACTIVITY_1”/><category android:name=“android.intentation.category.DEFAULT”/></into-filter>

把这个意向过滤器放在你的清单上,在你的活动标签里面。当您单击通知时,它将打开应用程序并直接转到您在click_action中定义的活动,在本例中为“open_ACTIVTY_1”。在该活动中,您可以通过以下方式获取数据:

捆绑包b=getIntent().getExtras();String someData=b.getString(“someData”);

我正在为我的android应用程序使用FCM,并使用这两种有效负载。下面是我使用的JSON示例:

{“to”:“FCM注册ID”,“通知”:{“title”:“标题”,“body”:“正文”,“icon”:“ic_notification”,“click_action”:“OPEN_ACTIVITY_1”},“数据”:{“someData”:“这是一些数据”,“someData2”:“etc”}}
8
  • “把那个intent-filter放在你的清单上,放在application标签里面。”。 2017年9月27日16:11
  • JSON dows不显示click_action键的位置。 2017年12月20日10:56
  • 这不是正确答案吗?什么是点击动作n它去哪里了?应该有人投反对票或清理这个
    – 拉纳
    2018年2月8日23:16
  • 1
    @KyryloZapylaiev我刚刚更正并更新了答案:“把那个意向过滤器放在你的清单上,放在你活动标签的里面”。 2019年4月30日6:08
  • 1
    @Josh已更新并格式化。你可以再检查一次 2019年4月30日6:08
55

2019年7月开始工作

Android编译SdkVersion 28、buildToolsVersion 28.0.3和firebase-message:19.0.1

在对所有其他StackOverflow问题和答案进行了数小时的研究,并尝试了无数过时的解决方案后,此解决方案在以下三种情况下显示了通知:

-应用程序位于前台:
通知由MyFirebaseMessagingService类中的onMessageReceived方法接收

-应用程序已被终止(它未在后台运行):FCM会自动将通知发送到通知托盘。当用户触摸通知时,通过调用具有android.intent.category的活动来启动应用程序。舱单上的发射器。您可以通过在onCreate()方法中使用getIntent().getExtras()来获取通知的数据部分。

-应用程序处于后台:FCM会自动将通知发送到通知托盘。当用户触摸通知时,通过启动包含android.intent.category的活动,应用程序将显示在前台。舱单上的发射器。由于我的应用程序在该活动中具有launchMode=“singleTop”,因此不会调用onCreate()方法,因为已经创建了同一类的一个活动,而是调用该类的onNewIntent()方法并使用intent.getExtras()获取通知的数据部分。

步骤:1-如果您这样定义应用程序的主要活动:

<活动android:name=“.MainActivity”android:label=“@string/app_name”android:largeHeap=“true”android:screenOrientation=“纵向”android:launchMode=“singleTop”><意向过滤器><action android:name=“.MainActivity”/><action android:name=“android.intent.action.MAIN”/><category android:name=“android.intentation.category.LAUNCHER”/><category android:name=“android.intentation.category.DEFAULT”/></into-filter></活动>

2-在MainActivity.class的onCreate()方法中添加这些行

意向i=getIntent();捆绑额外项=i.getExtras();if(额外!=空){for(字符串键:extras.keySet()){对象值=extras.get(键);Log.d(Application.APPTAG,“onCreate:Key:”+Key+“Value:”+Value处收到的额外服务);}String title=extras.getString(“title”);字符串消息=extras.getString(“body”);if(message!=空&&message.length()>0){getIntent().removeExtra(“身体”);showNotificationInADialog(标题、消息);}}

将这些方法添加到同一MainActivity.class:

@覆盖NewIntent上的公共无效(Intent Intent){//创建此类的新意图时调用。//主要的情况是当应用程序处于后台时,通知到达托盘,用户触摸通知super.onNewIntent(意向);Log.d(Application.APPTAG,“onNewIntent-启动”);捆绑额外项=intent.getExtras();if(extra!=null){for(字符串键:extras.keySet()){对象值=extras.get(key);Log.d(Application.APPTAG,“在onNewIntent:Key:”+Key+“Value:”+Value上接收的附加值);}String title=extras.getString(“title”);字符串消息=extras.getString(“body”);if(message!=空&&message.length()>0){getIntent().removeExtra(“主体”);showNotificationInADialog(标题、消息);}}}private void showNotificationInADialog(字符串标题,字符串消息){//显示带有所提供标题和消息的对话框警报对话框。Builder Builder=新AlertDialog。建筑商(本);builder.setTitle(标题);builder.setMessage(消息);builder.setPositiveButton(“确定”,新的DialogInterface.OnClickListener(){public void onClick(DialogInterface对话框,int whichButton){dialog.cancel();}});AlertDialog警报=builder.create();alert.show();}

3-创建类MyFirebase,如下所示:

软件包com.yourcompany.app;导入android.content。意向;导入android.util。日志;导入com.google.firebase.messaging。FirebaseMessagingService;导入com.google.firebase.messaging。远程消息;公共类MyFirebaseMessagingService扩展了FirebaseMessagingService{公共MyFirebaseMessagingService(){super();}@覆盖public void onMessageReceived(远程消息远程消息){Log.d(Application.APPTAG,“myFirebaseMessagingService-onMessageReceived-message:”+远程消息);意向对话框Intent=新意向(this,NotificationActivity.class);dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);dialogIntent.putExtra(“消息”,远程消息);启动活动(dialogIntent);}}

4-创建一个新类NotificationActivity.class,如下所示:

软件包com.yourcompany.app;导入android.app。活动;导入android.app。警报对话框;导入android.content。DialogInterface;导入android.os。捆绑;导入android.util。日志;导入androidx.appcompat.app。应用兼容活动;导入androidx.appcompat.view。上下文主题包装器;导入com.google.firebase.messaging。远程消息;公共类NotificationActivity扩展了AppCompatActivity{私人活动情境;@覆盖protected void onCreate(捆绑保存的实例状态){super.onCreate(savedInstanceState);上下文=此;捆绑额外项=getIntent().getExtras();Log.d(Application.APPTAG,“NotificationActivity-onCreate-extras:”+额外项);if(额外==空){context.finish();回报;}RemoteMessage msg=(远程消息)extras.get(“msg”);如果(消息==空){context.finish();回报;}远程消息。通知通知=msg.getNotification();if(通知==空){context.finish();回报;}字符串对话框消息;尝试{dialogMessage=通知.getBody();}catch(异常e){context.finish();回报;}String dialogTitle=通知.getTitle();if(dialogTitle==null||dialogTile.length()==0){dialogTitle=“”;}警报对话框。生成器生成器=新警报对话框。生成器(新ContextThemeWrapper(context,R.style.myDialog));builder.setTitle(dialogTitle);builder.setMessage(dialogMessage);builder.setPositiveButton(getResources().getString(R.string.accept),新的DialogInterface。OnClickListener(){public void onClick(DialogInterface对话框,int whichButton){dialog.cancel();}});AlertDialog警报=builder.create();alert.show();}

}

5-将这些行添加到标签内的应用程序清单中

<服务android:name=“.MyFirebaseMessagingService”android:exported=“false”><意向过滤器><action android:name=“com.google.firebase.MESSAGING_EVENT”/></into-filter></服务><meta-data安卓:name=“com.google.firebase.message.default_notification_channel_id”安卓:value=“@string/default_noteification_cchannel_id”/><activity android:name=“.NotificationActivity”android:theme=“@style/myDialog”></activity><元数据android:name=“com.google.firebase.message.default_notification_icon”android:resource=“@drawable/notification_icon”/><元数据android:name=“com.google.firebase.message.default_notification_color”android:resource=“@color/color_accent”/>

6-在Application.java onCreate()方法或MainActivity.class onCreate)方法中添加这些行:

//通知频道创建if(Build.VERSION.SDK_INT>=Build.VERTION_CODES.O){//创建频道以显示通知。String channelId=getResources().getString(“default_channel_id”);String channelName=getResources().getString(“一般公告”);NotificationManager NotificationManager=getSystemService(NotificationManager.class);notificationManager.createNotificationChannel(新的通知频道(channelId,channelName,通知管理器。IMPORTANCE_LOW));}

完成。

现在,为了在上述3种情况下都能正常工作,您必须通过以下方式从Firebase web控制台发送通知:

在“通知”部分中:通知标题=通知对话框中显示的标题(可选)通知文本=要向用户显示的消息(必需)然后在Target部分:App=你的Android应用程序以及在“附加选项”部分:Android通知频道=default_Channel_id自定义数据key:title值:(此处的文本与Notification部分的title字段中的文本相同)key:body值:(此处的文本与Notification部分的Message字段中的文本相同)键:click_action value:。主要活动声音=禁用
到期时间=4周

您可以使用API 28和Google Play在Emulator中调试它。

编码快乐!

12
  • 2
    谢谢你的回答。 2019年10月10日12:36
  • @alvaro,如果我想在收到通知时打开Url,我如何处理
    – 英语
    2019年11月15日15:19
  • 2
    当应用程序关闭或关闭时,无法在vivo opp手机中工作 2019年11月19日8:02
  • 2
    这是最新的答案,Firebase文档现在写道:当你的应用程序在后台时,Android会将通知消息定向到系统托盘。默认情况下,用户点击通知会打开应用程序启动器。这包括包含通知和数据有效负载的消息。在这些情况下,通知将发送到设备的系统托盘,数据有效载荷将在启动程序Activity意图的附加部分中发送。(firebase.google.com/docs/cloud-message/android/…)这么多古老的答案已经过时了 2020年1月20日22:40
  • 1
    你不认为任何人都可以向你的启动程序发送任意消息吗。它会显示来自不可信来源的任何消息吗?
    – 宝贝
    2021年2月10日13:58
38

根据文档

在后台应用程序中处理消息

当你的应用程序处于后台时,Android会发出通知消息发送到系统托盘。用户点击通知将打开默认情况下,应用程序启动器。

这包括同时包含通知和数据的消息有效载荷。在这些情况下,通知将发送到设备的系统托盘,数据有效载荷在启动程序Activity的意图。

如果要打开应用程序并执行特定操作,请设置单击通知负载中的action并将其映射到一个意图在要启动的“活动”中筛选。例如,set单击OPEN_ACTIVITY_1的_action以触发类似以下内容:

<intent-filter><action android:name=“OPEN_ACTIVITY_1”/><category android:name=“android.intentation.category.DEFAULT”/></into-filter>

编辑:

基于此线:

您无法使用Firebase Console设置click_action有效负载。您可以尝试使用curl命令或自定义http服务器进行测试

curl--header“授权:key=<YOUR_key_GOES_HERE>”--header Content-Type:“application/json”https://fcm.googleapis.com/fcm/send  -d“{\”到\“:\”/topics/news\“,\”通知\“:{\“title\”:\“单击操作消息\”,\“text\”:“示例消息\”,\“click_action\”:\“OPEN_ACTIVITY_1\”}”
5
  • 1
    你是对的。我读过这些文件。但我不知道该把这个放在哪里?我必须在该java文件的onMessageReceived上运行代码,因此我应该怎么做? 2016年6月8日19:27
  • 你无法使应用程序在后台自动调用onMessageReveiced。相反,您需要处理收到的意图并让处理程序调用它。或者最好实现由onMessageReveiced和您的意图处理调用的单独类/方法。我在主活动的onNewIntent中添加了处理程序,它对我来说很好。 2016年6月15日10:30
  • 回答@Parath Patel的问题太晚了,但也许这会帮助其他人解决同样的问题,请看我的答案stackoverflow.com/a/42279260/2734021 2017年2月23日21:43
  • 这次行动是为了什么?用于我的活动或Firebase消息服务?
    – 马赫迪
    2017年2月27日7:44
  • **在多个通知上重定向不起作用?例如:如果我有三个来自fcm的后台通知,使用“clickaction”,第一个通知成功重定向,然后单击2个通知,则活动重定向不起作用 2017年7月5日6:20
26

根据文件:2017年5月17日

当你的应用程序位于背景,安卓将通知消息定向到系统托盘。用户点击通知打开默认情况下的应用程序启动器.

这包括包含这两者的消息通知和数据有效载荷(以及从通知控制台发送的所有消息)。在这些情况下,通知将发送到设备的系统托盘,并且数据有效载荷是在您的意图之外交付的启动器活动。

因此,您应该同时使用有效负载通知+数据:

{“to”:“FCM注册ID”,“通知”:{“title”:“标题”,“body”:“正文”,“icon”:“ic_notification”},“数据”:{“someData”:“这是一些数据”,“someData2”:“etc”}}

没有必要使用click_action。你应该让你的前女友LAUNCHER活动

<activity android:name=“.MainActivity”><意向过滤器><category android:name=“android.intentation.category.LAUNCHER”/></into-filter></活动>

Java代码应位于MainActivity的onCreate方法上:

意向=getIntent();if(intent!=空&&intent.getExtras()!=null){捆绑额外项=intent.getExtras();String someData=extras.getString(“someData”);String someData2=extras.getString(“someData2”);}

您可以测试来自Firebase通知控制台。不要忘记填写“高级选项”部分中的自定义数据字段

1
26

要在后台捕获消息,您需要使用广播接收器

导入android.content。上下文导入android.content。意图导入android.util。日志导入androidx.legacy.content。唤醒广播接收器导入com.google.firebase.messaging。远程消息类FirebaseBroadcastReceiver:WakefulBroadcast接收器(){val TAG:String=FirebaseBroadcastReceiver::class.java.simpleName覆盖fun onReceive(上下文:上下文,意图:意图){val dataBundle=意向.extrasif(dataBundle!=空)for(dataBundle.keySet()中的key){Log.d(TAG,“dataBundle:”+key+“:”+dataBundles.get(key))}val remoteMessage=远程消息(数据包)}}

并将此添加到您的清单中:

<接收器android:name=“MY_PACKAGE_name.FirebaseBroadcastReceiver”android:exported=“true”android:permission=“com.google.android.c2dm.permission.SEND”><意向过滤器><action android:name=“com.google.android.c2dm.intent.RECEIVE”/></into-filter></接收器>
10
  • 7
    当应用程序处于后台时,这将真正接收通知消息。但它不会阻止默认的Firebase接收器处理它,因此消息仍会显示为通知警报。
    – 加利娅
    2016年10月5日15:37
  • 目前不起作用,所以这就是我提出这个解决方案的原因。谷歌错误库中有一个已归档的错误。你可能想看看。 2016年10月20日9:27
  • 你能在这里发布一个错误的链接吗
    – 加利娅
    2016年10月20日9:42
  • 1
    当应用程序被终止时,这显然不起作用。我已经试了几个小时了。由于某种原因,当应用程序处于后台时接收器工作,而当应用程序被终止时接收器不工作 2016年12月14日7:10
  • 当然,但这是另一个与此问题无关的问题XcodeNOOB。 2016年12月14日10:15
24

自从显示消息仅当应用程序位于前台时,从Firebase Notification UI发送的通知才有效。对于数据消息,需要对进行POST调用FCM公司

步骤

  1. 安装高级Rest客户端Google Chrome扩展在此处输入图像描述

  2. 添加以下标题

    钥匙:内容类型,价值:application/json

    钥匙:授权,价值:key=“您的服务器密钥”在此处输入图像描述

  3. 添加正文

    • 如果使用主题:

      {“至”:“/topics/topic_name”,“数据”:{“key1”:“value1”,“key2”:“value2”,}}
    • 如果使用注册id:

      {“registration_id”:“[{”id“},{id1}]”,“数据”:{“key1”:“value1”,“key2”:“value2”,}}

就是这样!。现在听听收到的消息像往常一样回调。

@覆盖公共void onMessageReceived(RemoteMessage RemoteMessage){Map<String,String>data=remoteMessage.getData();字符串value1=data.get(“key1”);字符串value2=data.get(“key2”);}
1
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用。当应用程序关闭时,什么事件可以帮助我检测何时在应用程序上收到数据有效负载? 2022年5月12日16:18
24
@覆盖public void onMessageReceived(远程消息远程消息){}

仅当应用程序处于前台时才在每次调用时调用

有一个覆盖方法每次都会调用此方法,无论前台或后台有什么应用程序或被终止,但此方法可用于此firebase api版本

这是你必须从gradle导入的版本

编译“com.google.firebase:firebase-message:10.2.1”

这就是方法

@覆盖公共无效处理意向(意向意向){super.handleIntent(意图);//你可以在这里获得你的数据//intent.getExtras().get(“your_data_key”)}

对于以前的firebaseapi,这种方法是不存在的,所以在这种情况下当应用程序处于后台时,会自动触发基本句柄。。。。现在你有了这个方法你想做什么。。。你可以在这里用这种方法。。。。。

如果您使用的是以前的版本,则默认活动将启动在这种情况下,你可以用同样的方法获得数据

if(getIntent().getExtras()!=null&&getIntent().getExtras().get(“your_data_key”)!=空){字符串strNotificaticaiton=getIntent().getExtras().get(“your_data_key”).toString();

//做你想做的事。。。。}

通常这是我们在通知中从服务器获得的结构

{“通知”:{“body”:“很酷的优惠。在过期之前获取!”,“title”:“平八折”,“icon”:“appicon”,“click_action”:“活动名称”//可选(如果需要)。。。。。},“数据”:{“产品id”:11,“product_details”:“详细信息…..”,“其他信息”:“……”}}

你想如何提供数据密钥取决于你,或者你想发出任何你能发出的通知。。。。。。。无论你在这里用同样的键给出什么,你都会得到那个数据。。。。。。。。。

如果你不发送点击操作,在这种情况下,当你点击通知时,默认活动将打开,但如果你想在应用程序处于后台时打开你的特定活动,你可以从这个on-handleIntent方法调用你的活动,因为每次都会调用这个方法

5
  • 我将firebase-messaging更新为10.2.1,在通知消息中添加了数据,它工作了。前景、背景和终止。谢谢 2017年6月27日18:43
  • 在Kotlin中,我得到这个错误:“FirebaseMessagingService”中的(44,5)“handleIntent”是最终的,不能被覆盖 2017年11月8日15:46
  • 它在firebase 11的版本之上无法工作
    – 维努46
    2019年9月11日6:44
  • handleIntent(处理意图)被呼叫com.google.firebase.消息。新_确定行动。使用时要小心。 2021年10月14日9:41
  • 这是正确的答案,谢谢。 2022年5月8日10:03
12

这样简单的总结

  • 如果您的应用程序正在运行;

    收到消息时()

是触发器。

  • 如果你的应用程序没有运行(被刷死);

    收到消息时()

不是由direclty触发和传递的。如果你有任何特殊的键值对。它们不起作用,因为onMessageReceived()不起作用。

我已经找到了这个方法;

在你的启动器活动中,输入这个逻辑,

protected void onCreate(捆绑保存的实例状态){super.onCreate(保存的实例状态,R.layout.activity_splash);if(getIntent().getExtras()!=null&&getIntent().getExtras().containsKey(“PACKAGE_NAME”){//做你想做的//如果我们不想开始的话,这是用来杀死应用程序的android.os。Process.killProcess(android.os.Process.myPid());}其他{//继续应用}}

在这个if块中,根据firebase UI搜索密钥。

在这个例子中,我的关键字和值与上面一样;(抱歉语言=)在此处输入图像描述

当我的代码工作时,我会得到“com.rda.note”。

android.os。Process.killProcess(android.os.Process.myPid());

用这行代码,我关闭了我的应用程序并打开了Google Play Market

快乐编码=)

0
12

2017年更新答案

以下是来自文档关于此:

在此处输入图像描述

1
9

我想出了各种情况,

当应用程序处于前景,收到消息时()方法从火力基地服务.所以pendingIntent(待定意向)将调用服务类中定义的。

当应用程序进入时背景,第一次活动被调用。

现在,如果您使用飞溅活动,然后必须记住飞溅活性将被调用,否则如果没有splashActivity,那么无论第一个活动是什么,都将被调用。

然后你需要检查getIntent()第一个活动看看有没有。如果一切正常,你会看到bundle在那里,里面填写了值。如果数据标签从服务器发送的内容如下所示,

“数据”:{“user_name”:“arefin sajib”,“value”:“用户名通知”}

然后在第一个活动中,您将看到,有一个有效的意图(getIntent()不为空),有效的bundle和bundle内部,会有上面提到的整个JSON数据作为钥匙.

对于此场景,用于提取值的代码如下所示,

if(getIntent()=null){捆绑包=getIntent().getExtras();if(bundle!=null){尝试{JSONObject对象=新JSONObjects(bundle.getStringExtra(“数据”));String user_name=object.optString(“user_name”);}catch(JSONException e){e.printStackTrace();}}}
1
  • 这真的解决了我的问题。尝试了许多其他事情。但这真的很管用。谢谢 2022年2月10日12:29
8

我也有同样的问题。在探究了为什么在没有数据的情况下有意调用我的MainActivity之后,我意识到我的LAUNCHER活动(如清单中所示)是SplashActivity。在那里,我找到了消息数据并将其转发给MainActivity。像沙姆一样工作。我相信这可以帮助某人。

谢谢你的回答。

2
  • 谢谢你的建议。这对我也很管用。我的SplashScreen达到了目的,在MainActivity中不可用
    – 尼奥
    2020年12月4日12:37
  • 仍然有效的解决方案,谢谢! 2021年11月1日18:25
5

删除通知负载完全根据您的服务器请求。发送仅数据然后处理它收到消息时(),否则为您的收到的消息当应用程序处于后台或被终止时,将不会触发。

以下是我从服务器发送的内容:

{“数据”:{“id”:1,“错过的请求”:5“addAnyDataHere”:123},“至”:“fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs……”}

这样您就可以在onMessageReceived(远程消息消息)像这样:(假设我必须得到身份证)

对象obj=message.getData().get(“id”);if(obj!=空){int id=Integer.valueOf(obj.toString());}

类似地,您可以从中获取从服务器发送的任何数据收到的消息().

1
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用。当应用程序关闭时,什么事件可以帮助我检测何时在应用程序上收到数据有效负载? 2022年5月12日16:16
5

感谢大家的回答。但我通过发送数据报文而不是发送通知.服务器代码

<?php(电话)$url=“https://fcm.googleapis.com/fcm/send";$token=“C-l6T_a7HouUK***”;$serverKey=“AAAAaOcKS00:******”;define('API_ACCESS_KEY',$serverKey);$registrationIds=数组($token);//准备包裹$msg=数组(“message”=>“这是一条消息。”。消息','title'=>'这是一个标题。标题','字幕'=>'这是一个字幕。字幕','tickerText'=>'此处显示Ticker文本。。。此处为Ticker文本。。。股票代码文本这里',“振动”=>1,“声音”=>1,“largeIcon”=>“large_con”,“smallIcon”=>“small_icon”);$fields=数组(“registration_ids”=>$registrationIds,“数据”=>$msg);$headers=数组('授权:密钥='。API_ACCESS_钥匙,'内容类型:application/json');$ch=curl_init();curl_setopt($ch,CURLOPT_URL,'https://android.googleapis.com/gcm/send' );curl_setopt($ch,CURLOPT_POST,true);curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);curl_setopt($ch,CURLOPT_RETURNTTRANSFER,true);curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($fields));$result=curl_exec($ch);curl_close($ch);echo$result;?>

并捕获了onMessageReceived中的数据

公共类MyFirebaseMessagingService扩展了FirebaseMessagingService{private static final String TAG=“MyFirebaseMsgService”;@覆盖public void onMessageReceived(RemoteMessage RemoteMessage){Log.d(标签,“发件人:”+remoteMessage.getFrom());//检查消息是否包含数据有效负载。if(remoteMessage.getData().size()>0){Log.d(TAG,“消息数据有效载荷:”+remoteMessage.getData());发送通知(remoteMessage.getData().get(“消息”));}//检查消息是否包含通知负载。else if(remoteMessage.getNotification()!=null){Log.d(TAG,“消息通知正文:”+remoteMessage.getNotification().getBody());发送通知(remoteMessage.getNotification().getBody());}}private void sendNotification(字符串消息正文){意向=新意向(this,Notify.class).putExtra(“msg”,messageBody);intent.addFlags(intent.FLAG_ACTIVITY_CLEAR_TOP);PendingIntent PendingIntent=PendingIntent.getActivity(this,0/*请求代码*/,intent,待定意向。FLAG_ONE_SHOT);字符串channelId=“idddd”;Uri defaultSoundUri=铃声管理器.getDefaultUri(铃声管理器.TYPE_NOTIFICATION);通知Compat。生成器通知Builder=新的NotificationCompat。生成器(MyFirebaseMessagingService.tis).setSmallIcon(R.mipmap.ic_launcher).setContentTitle(“FCM消息”).setContentText(消息正文).setAutoCancel(true).setSound(默认声音URI).setContentIntent(pendingIntent);NotificationManager通知管理器=(通知管理器)getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.notify(0/*通知ID*/,notificationBuilder.build());}}
  • @Tabishkhan是的,兄弟,如果你有什么问题,可以问我……谢谢 2019年3月6日15:58
  • 1
    嗨@AndroidSanaullah,你能解释一下服务器代码的第一部分吗?你实际上把它放在哪里了?我面临着同样的问题,但我不太理解服务器部分,你在使用邮递员吗?
    – 该死的
    2019年4月30日22:45
  • 卷曲用于请求,所有参数都传递给它。@Shid 2019年8月14日8:01
4

一般来说

FCM(Firebase云消息传递)中有两种类型的消息:

  • 显示消息:这些消息仅在应用程序处于以下状态时触发onMessageReceived()回调前景

  • 数据消息:这些消息触发onMessageReceived()回调,即使您的应用程序位于前景/背景/终止

数据消息例子:

{ “到”:“/path”,“数据”:{ “my_custom_key”:“我的自定义值”,“my_custom_key2”:真} }

显示消息例子:

{“通知”:{“title”:“标题”,“body”:“正文”,“icon”:“ic_notification”,“click_action”:“OPEN_ACTIVITY_1”}}

Android端可以处理如下通知:

公共类MyFirebaseMessagingService扩展了FirebaseMessagingService{@覆盖公共void onMessageReceived(RemoteMessage RemoteMessage){映射<String,String>data=remoteMessage.getData();字符串myCustomKey=data.get(“my_custom_key”);} }

有关FCM的更多详细信息,请访问:在Android上设置Firebase云消息客户端应用程序

1
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用。当应用程序关闭时,什么事件可以帮助我检测何时在应用程序上收到数据有效负载? 2022年5月12日16:16
4

我在中添加了以下代码firebase-messaging-sw.js,

messaging.onBackgroundmessage((有效负载)=>{console.log(“检测到后台消息!!”);console.log(“消息:”,有效负载);})

每次在后台收到消息时都会触发此操作。但我无法在主线程中使用有效负载,因为软件不支持它。所以我进行了大量研究,并在Android论坛中找到了解决方案。

因此,解决方案是我们必须从请求有效负载中删除通知有效负载。

所以我把有效载荷从

{“通知”:{“title”:“你好”,“body”:“订阅AMAL MOHAN N youtube频道”},“to”:“your-browser-token”,“数据”:{“value1”:“文本”,“值2”:“”,“value3”:“示例3”,“value4”:“sample4”}}

{“to”:“your-browser-token”,“数据”:{“value1”:“文本”,“值2”:“”,“value3”:“示例3”,“value4”:“示例4”}}

有效载荷的变化自动使接收消息()前台消息和后台消息中的触发器。

我在一个Android论坛上发现了这个,这对我很有用!如果这对你有用,请告诉我。

1
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用。当应用程序关闭时,什么事件可以帮助我检测何时在应用程序上收到数据有效负载? 2022年5月12日16:16
4

为了能够在应用程序处于后台时从发送的firebase通知中检索数据,您需要添加单击_操作通知数据集中的条目。

在firebase控制台中设置通知的其他选项,如下所示:(你必须在这里包含你想在应用程序中检索的任何额外数据):将click_action添加到firebase通知

并在要启动的活动下的清单文件中包含意图过滤器

<活动android:name=“.MainActivity”android:exported=“true”android:label=“@string/app_name”android:theme=“@style/theme.MyApp.SplashScreen”><意向过滤器><action android:name=“android.intent.action.MAIN”/><category android:name=“android.intentation.category.LAUNCHER”/><意向过滤器><action安卓:name=“FIREBASE_NOTIFICATION_CLICK”/><category android:name=“android.intentation.category.DEFAULT”/></into-filter></活动>

然后在活动中获取捆绑数据关于NewIntent:

@覆盖受保护的NewIntent无效(Intent Intent){super.onNewIntent(意向);捆绑数据=intent.getExtras();if(数据!=空){for(字符串键:data.keySet()){对象值=data.get(key);//对数据项执行您想要的操作Log.d(FIREBASE_TAG,“Key:”+Key+“Value:”+Value);Toast.makeText(this,“Key:”+Key+“….Value:”+Value,Toast.LENGTH_LONG).show;}}}

当你的应用程序位于前台时,你可以设置你的收到消息时这样地:

@覆盖public void onMessageReceived(@NonNull RemoteMessage消息){Log.d(FIREBASE_TAG,“消息发件人:”+消息.getFrom());if(message.getNotification()!=空){意向=新意向(this,MainActivity.class);intent.addFlags(intent.FLAG_ACTIVITY_CLEAR_TOP);Map<String,String>data=message.getData();if(data!=null&&!data.isEmpty()){for(Map.Entry<String,String>Entry:data.entrySet()){intent.putExtra(entry.getKey(),entry.getValue());}}//.......//实现其余代码以显示通知//}}

即使应用程序位于后台和前台,也可以轻松发送消息,如下所示:-要使用API发送消息,可以使用一个名为AdvancedREST Client的工具,它是一个chrome扩展,并使用以下参数发送消息。

Rest客户端工具链接:https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbbjeloo

使用此url:-https://fcm.googleapis.com/fcm/send内容类型:application/json授权:key=您的服务器密钥From或Authoization密钥(参见下文参考)

{“数据”:{“图像”:“https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg",“message”:“使用API的Firebase推送消息”“AnotherActivity”:“True”},“to”:“设备id或设备令牌”}

可以通过访问Google开发人员控制台并单击项目左侧菜单上的凭据按钮来获取授权密钥。在列出的API密钥中,服务器密钥将是您的授权密钥。

您需要将接收器的tokenID放在使用API发送的POST请求的“to”部分。

您希望在后台处理MessageReceived(RemoteMessage RemoteMessage),仅发送数据部分通知部分如下:

“data”:“image”:“”,“message”:“Firebase Push message Using API”,

“AnotherActivity”:“True”,“to”:“设备id或设备令牌”

通过此onMessageRecivied是调用后台和前台,无需在启动程序活动中使用通知托盘处理通知。使用以下内容处理数据有效负载:

public void onMessageReceived(远程消息远程消息)if(remoteMessage.getData().size()>0)Log.d(TAG,“消息数据有效载荷:”+remoteMessage.getData());

提供的解决方案在我的情况下不起作用。

最后,我发现一些电池优化应用程序可以让用户控制是否允许或阻止应用程序发送通知。在我的情况下,是三星的Smart Manager在我的应用程序被删除/从最近的列表中清除后立即自动阻止了我的应用。

为我的应用程序关闭该功能是我能找到的唯一解决方案。

2

2018年6月答案-

您必须确保消息中没有“notification”关键字。仅包含“数据”,应用程序将能够处理onMessageReceived中的消息,即使在后台或已终止。

使用云函数:

常量消息={token:tokenid,//通过查询firebase中的数据获取设备令牌id数据:{标题:“我的自定义标题”,正文:“my_custom_body_message”}}return admin.messaging().send(message).then(response=>){//处理响应});

然后在onMessageReceived()中,在类中扩展com.google.firebase.messaging。FirebaseMessaging服务:

if(数据!=空){Log.d(TAG,“数据标题为:”+data.get(“标题”);Log.d(TAG,“数据体为:”+data.get(“体”);}//使用正文、标题和其他任何您想要的内容构建通知。
  • 你有任何来源吗,它安全吗? 2019年1月9日6:09
  • 它很安全,我在应用程序中使用它。然而,自发布6个月以来,我记不清来源了——我想这是firebase文档。 2019年1月12日19:34
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用。当应用程序关闭时,什么事件可以帮助我检测何时在应用程序上收到数据有效负载? 2022年5月12日16:15
2

根据OAUTH 2.0:

由于FCM现在使用OAUTH 2,因此在这种情况下会出现身份验证问题

所以我阅读了firebase文档,并根据文档发布数据消息的新方法是:;

邮政:https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

标题

键:内容类型,值:application/json

授权

承载人YOUR_TOKEN

示例正文

{“消息”:{“主题”:“xxx”,“数据”:{“body”:“这是Firebase云消息主题消息!”,“title”:“FCM消息”}}}

在url中有数据库Id,您可以在firebase控制台上找到它。(转到项目设置)

现在让我们接受代币(仅1小时有效):

首先在Firebase控制台中打开设置>服务帐户。单击生成新私钥,安全存储包含密钥的JSON文件。我需要这个JSON文件来手动授权服务器请求。我下载了它。

然后我创建了一个node.js项目,并使用此函数获取我的令牌;

var PROJECT_ID='YOUR_PROJECT_ID';var HOST='fcm.googleapis.com';var PATH='/v1/projects/'+PROJECT_ID+'/messages:send';var MESSAGING_SCOPE='https://www.googleapis.com/auth/firebase消息';var SCOPES=[MESSAGING_SCOPE];router.get('/',函数(req,res,next){res.render(“索引”,{title:“快速”});getAccessToken().then(函数(accessToken)){console.log(“TOKEN:”+accessToken)})});函数getAccessToken(){return new Promise(函数(resolve,reject){var key=require('./YOUR_DOWNLOADED_JSON_FILE.JSON');var jwtClient=新的google.auth。JWT公司(密钥客户端电子邮件,无效的,钥匙.专用钥匙,范围,无效的);jwtClient.authorize(函数(err,标记){if(错误){拒绝(err);回报;}解析(tokens.access_token);});});}

现在我可以在我的发帖请求中使用此令牌。然后我发布我的数据消息,它现在由我的应用程序onMessageReceived函数处理。

1
2

自2019年以来,谷歌Firebase的API发生了重大变化我的意思是:'com.google.firebase:firebase-message:18.0.0'

在18.0.0中,他们删除了MyFirebaseInstanceID服务你需要拿到代币我的Firebase信息服务所以你只需要写:

@覆盖public void onNewToken(字符串标记){Log.d(TAG,“刷新令牌:”+令牌);}

并且在AndroidManifest.xml中,您必须删除:

<service android:name=“.service.MyFirebaseInstanceIDService”><意向过滤器><action android:name=“com.google.firebase.INSTANCE_ID_EVENT”/></into-filter></服务>

此外,建议您设置默认值以自定义通知的外观。您可以指定自定义默认图标和自定义默认颜色,只要通知负载中没有设置等效值,就会应用这些图标和颜色。

在应用程序标记中添加以下行,以设置自定义默认图标和自定义颜色:

<元数据android:name=“com.google.firebase.message.default_notification_icon”android:resource=“@drawable/ic_notification”/><元数据android:name=“com.google.firebase.message.default_notification_color”android:resource=“@color/colorAccent”/><元数据android:name=“com.google.firebase.message.default_notification_channel_id”android:value=“@string/push_channel”/>

现在,要在后台应用程序中处理通知消息,您应该在第一个活动中定义Intent,即使它是SplashScreen。当您的应用程序在后台时,Android会将通知消息定向到系统托盘。默认情况下,用户点击通知会打开应用程序启动器。

例如,如果您的Json是这样的:

“数据”:{“消息”:“2”,“标题”:“1”,“pushType”:“banner”,“bannerLink”:“http://www.google.com网站",“图像”:“https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

您只需要编写一个简单的意图即可获得这些值:

捆绑额外功能=intent.getExtras();String bannerLink=extras.getString(“bannerLink”);...String channelId=extras.getString(“channelId”);
0

除了上述回答之外,如果您正在使用测试推送通知FCM控制台,“data”键和对象是已添加到推送通知捆绑包。因此,当应用程序处于后台或被终止时,您不会收到详细的推送通知。

在这种情况下,您必须选择后端管理控制台来测试应用程序后台场景。

在这里,您将在推送包中添加“数据”键。因此,将按预期显示详细的推送。希望这对少数人有帮助。

1
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用 2022年5月12日16:14
0

使用此代码,您可以在后台/前台获得通知并执行操作:

//通知中的数据应采用这种格式{“至”:“/xyz/Notifications”,“数据”:{“key1”:“标题通知”,“key2”:“描述通知”}}

应用程序内使用此代码:

@覆盖public void onMessageReceived(远程消息远程消息){super.onMessageReceived(远程消息);String key1Data=remoteMessage.getData().get(“key1”);//根据您的需要使用key1Data}
2
  • //数据应该以这种格式从通知{“to”:“/xyz/Notifications”,“Data”:{“key1”:“title notification”,“key2”:“description notification”}}}如何在php服务中编写此代码? 2019年2月20日13:02
  • 嗨,你能详细说明一下吗?我目前正在向使用FCM的离子应用程序发送仅数据有效负载。如果应用程序在后台/前台,则工作正常。但在应用程序关闭时不起作用。当应用程序关闭时,什么事件可以帮助我检测何时在应用程序上接收到数据负载? 2022年5月12日16:15
0

我通过使用广播消息解决了这个问题。

创建广播并从服务工作者发送广播消息中的有效负载。

然后在应用程序中接收有效负载并按您希望的方式处理它。

0

2023年1月对于那些实现最新Firebase云消息(FCM)的用户,您可能不限于发送数据通知当应用程序位于背景完全关闭。正如这里的一些答案所解释的,简短版本是:

在启动程序活动中,监视启动时的附加项; 测试您的FCM中的唯一密钥数据在列表中; 如果存在,获取必要的数据并调用活动来处理您想要进行的处理。

//火力基地//[开始句柄_数据_附加]if(getIntent().getExtras()!=null){布尔fcmExtraFlag=false;for(字符串键:getIntent().getExtras().keySet()){对象值=getIntent().getExtras().get(key);Log.d(标签,“键:”+键+“值:”+值);if(key.equalsIgnoreCase(“tracerId”)){//测试您已知的密钥,确保它来自fcm//这一定是来自通知(系统)托盘//无论应用程序是在后台还是完全关闭,都会出现这种情况//一般来说,这可能是主要活动,因为它已经设置了intent-filterfcmExtraFlag=true;}}//选择fcm值(如果存在),并相应地通知和/或处理//您可以添加时间查找以忽略延迟的(经过时间的)查找;并忽略if(fcmExtraFlag){字符串tracerId=(String)getIntent().getExtras().get(“tracerId”);//根据需要准备数据字符串tracerData=tracerId+“>”+data-one+“>“+data-two;String msgBody=“这是一个测试通知;收到的数据:”+tracerId;字符串fcmMessage=msgBody;//直接或以任何方式启动确认活动SidUtils.firebaseStartConfirms(消息体,tracerData,this);}}//[结束handle_data_extras]

如前所述,如果可能的话,这应该在您的主活动中,以便处理您的应用程序实际关闭的情况,而不仅仅是在后台。单击系统托盘上的应用通知将触发这些操作。

0

此情况仅适用于firebase管理员通知如果应用程序在后台,FirebaseMessagingService不会被触发

要处理此情况,请转到启动器活动,检查所附的意图捆绑包,并使用此代码打印出所有数据:

意图?。额外费用?。let{捆绑->for(bundle.keySet()中的键){val值=束[键]Log.d(“NotificationData”,String.format(“%s%s(%s)”),key,value.toString(),value!!。javaClass.name))}}

签入日志显示所有数据类型的数据;

例子:

我想从通知中获取周和标题将使用此代码

意图?。额外费用?。让{it->if(it.containsKey(“周”)){}if(it.containsKey(“标题”)){}

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.