在后台运行应用程序时未调用Firebase onMessageReceived


232

我正在使用Firebase,并测试在后台运行时从服务器向我的应用发送通知。通知已成功发送,甚至出现在设备的通知中心,但是当出现通知或即使我单击通知时,也不会调用FCMessagingService中的onMessageReceived方法。

当我在我的应用程序处于前台时对其进行测试时,将调用onMessageReceived方法,并且一切正常。当应用程序在后台运行时,会发生此问题。

这是预期的行为,还是我可以解决此问题的方法?

这是我的FBMessagingService:

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class FBMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.i("PVL", "MESSAGE RECEIVED!!");
        if (remoteMessage.getNotification().getBody() != null) {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
        } else {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
        }
    }
}

除了json主体之外,您的onTokenRefresh代码在哪里?您是否已完成Android安装程序
加藤

4
通知的json主体是什么意思?另外,我的onTokenRefresh代码位于FirebaseInstanceID服务内部。
Cyogenos '16

您可以张贴您要发送的样本有效载荷吗?
AL。


Answers:


144

这可以按预期工作,仅当您的应用程序位于前台时,通知消息才会传递到onMessageReceived回调。如果您的应用程序处于后台或关闭状态,则通知中心中会显示一条通知消息,并且该消息中的所有数据都将传递到由于用户点击通知而启动的意图

您可以指定click_action来指示在用户点击通知时应启动的意图。如果未指定click_action,则使用main活动。

启动意图后,您可以使用

getIntent().getExtras();

检索包含与通知消息一起发送的所有数据的Set。

有关通知消息的更多信息,请参阅docs


6
click_action当我使用Firebase Notification Console时,有什么方法可以设置?
Nii Laryea

6
好的,但是如果应用程序被杀死(没有前台或后台)怎么办?
michalu

3
但是如何禁用用户丢弃通知?因为如果用户丢弃它,则意味着将跳过所有数据...对吗?
Aleksey Timoshchenko '16

4
正确!因此,在向Android发送通知消息时,随附的数据应为可增强通知体验的数据。它不应该是应用程序关键数据,即使用户取消了通知,也应使用数据消息获取应用程序所需的数据。
亚瑟·汤普森

3
这并不完全正确。如果消息仅包含数据而不是通知有效负载,则无论应用程序是否处于前台,消息都将始终传递到onMessageReceive。
JacksOnF1re

125

notification从您的服务器请求中完全删除字段data发送并处理它,onMessageReceived()否则onMessageReceived()当应用程序在后台或被杀死时,您将不会被触发。

不要忘记"priority": "high"在通知请求中包含字段。根据文档:数据消息以正常优先级发送,因此它们不会立即到达;这也可能是问题。

这是我从服务器发送的内容

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
  "priority": "high"
}

因此,您可以onMessageReceived(RemoteMessage message)像这样接收数据。...说我必须获得身份证

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }

9
我发现如果仅发送数据消息,则从任务管理器中清除的App将无法获得通知。这是否是预期的行为?
Prabhjot Singh

2
这是我在后台接收消息的解决方案!
Ray Hulha'1

5
在奥利奥(Oreo)中,当应用程序被杀死时,不会调用onMessageReceived。我只是有数据的有效载荷。你有什么更新吗?
萨米尔·曼格罗里亚

2
奇迹般有效!
6

3
爱你很多答案:p
艾哈迈德·阿尔斯兰

63

此方法handleIntent()已被弃用,因此可以按以下方式处理通知:

  1. 前景状态:单击通知将转到您在按语法创建通知时提供的待处理Intent活动,该活动通常是使用通知的数据有效负载创建的。

  2. 后台/终止状态-系统本身在此处基于通知有效负载创建通知,单击该通知将带您进入应用程序的启动器活动,您可以在其中使用任何生命周期方法轻松获取Intent数据。


谢谢!!!我在这个问题上失去了几天,而这个救了我。
伊戈尔·扬科维奇(IgorJanković)

确实是完美的解决方案!
EduXavier

4
我正在handleIntent(Intent intent)中处理通知显示逻辑,但是当应用程序在后台运行时,将显示2条通知,其中一条是我创建的,另一条是默认情况下的,其中包含来自通知的整个消息。
Joyson

5
太棒了,但是OnMessageReceived在这种情况下我看不到有什么用!
Alaa AbuZarifa

8
我有com.google.firebase:火力的消息:11.6.2及handleIntent是最终now.Check stackoverflow.com/questions/47308155/...
Ronak Poriya

31

这是有关Firebase消息的更清晰的概念。我从他们的支持团队那里找到了它。

Firebase具有三种消息类型

通知消息:通知消息可在后台或前台使用。当应用程序处于后台时,通知消息将传递到系统托盘。如果应用程序在前台,则消息由onMessageReceived()didReceiveRemoteNotification回调处理。这些本质上就是所谓的显示消息。

数据消息:在Android平台上,数据消息可以在后台和前台工作。数据消息将由onMessageReceived()处理。这里有一个特定于平台的注释:在Android上,可以在用于启动活动的Intent中检索数据有效负载。要详细说明,如果有的话"click_action":"launch_Activity_1",可以通过getIntent()only 检索此意图Activity_1

带有通知和数据有效负载的消息:在后台时,应用程序会在通知托盘中接收通知有效负载,并且仅在用户点击通知时处理数据有效负载。在前台时,您的应用程序会收到一个同时具有两个有效负载的消息对象。其次,click_action参数通常用于通知有效负载中,而不用于数据有效负载中。如果在数据有效载荷内部使用,则此参数将被视为自定义键值对,因此您需要实现自定义逻辑以使其按预期工作。

另外,我建议您使用onMessageReceived方法(请参阅数据消息)提取数据束。根据您的逻辑,我检查了bundle对象,但未找到预期的数据内容。这里是对类似情况的参考,可能会提供更多的清晰度。

从服务器端,firebase通知应为以下格式

服务器端应发送“通知”对象。我的“通知”对象不足,TargetActivity没有使用发送消息getIntent()

正确的消息格式如下:

{
 "data": {
  "body": "here is body",
  "title": "Title"
 },
"notification": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
 "to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

这是有关Firebase消息的更清晰的概念。我从他们的支持团队那里找到了它。

有关更多信息,请访问我的这个线程这个线程


3
值得一提的是,如果设备处于深度打ze模式(Android 7.0中引入),则不会收到“数据消息”。小心那些!
Sameer J

30

我有同样的问题。使用“数据消息”而不是“通知”会更容易。数据消息始终加载onMessageReceived类。

在该课程中,您可以使用notificationbuilder发出自己的通知。

例:

 @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
    }

    private void sendNotification(String messageTitle,String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);

        long[] pattern = {500,500,500,500,500};

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setLights(Color.BLUE,1,1)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

7
谢谢..我更改了服务器代码,并使用“数据”代替了“通知”,现在它可以正常工作了,
Mahesh Kavathiya

5
@Koot仅当应用程序在前台时才起作用,而在后台时则不起作用。您能在两种情况下帮助我触发此事件吗?
Anant Shah

@AnantShah您到Firebase服务器的POST看起来如何?
Koot

3
实际上,这里有三种可能的情况。1)前台应用。2)后台应用程序。3)应用未运行。正如你所说,一个“数据”的消息将在在前两种情况下可以接收,但不是在第三种情况下,当应用程序没有运行。为了满足这三种情况,您需要在消息中设置“ notification”字段。(如果您想同时支持iOS和Android客户端,也是个好主意)
Steve Moseley 2016年

1
即使在应用程序未运行的情况下,我仍然会从onmessagereceived函数的服务器上获取消息。我同意您的看法,如果您也想支持ios,最好使用“通知”。
Koot

21

根据Firebase Cloud Messaging文档-如果Activity位于前台,则将调用onMessageReceived。如果“活动”处于后台或关闭状态,则通知消息将显示在通知中心中,用于启动应用程序活动。如果您的应用程序在后台运行,则可以通过单击通知来调用自定义活动,方法是调用rest服务api进行firebase消息传递,方法是:

网址-https : //fcm.googleapis.com/fcm/send

方法类型-POST

Header- Content-Type:application/json
Authorization:key=your api key

车身/有效载荷:

{ "notification": {
    "title": "Your Title",
    "text": "Your Text",
     "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
  },
    "data": {
    "keyname": "any value " //you can get this data as extras in your activity and this data is optional
    },
  "to" : "to_id(firebase refreshedToken)"
} 

并在您的应用程序中使用此代码,您可以在活动中添加以下代码以进行调用:

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

我在哪里创建意图并使其打开特定活动?我知道这在清单中注册了OPEN_ACTIVITY_1意图,但是我实际在哪里调用呢?
Cyogenos


我们应该从意图过滤器中调用活动吗?还是手动启动onMessageReceived
CoolMind

14

基于以下情况调用onMessageReceived(RemoteMessage remoteMessage)方法。

  • 通知数据块的FCM响应
{
  
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. 前景中的应用程序:

调用onMessageReceived(RemoteMessage remoteMessage),在通知栏中显示LargeIcon和BigPicture。我们可以从通知数据块中读取内容

  1. 后台应用程序:

如果未调用onMessageReceived(RemoteMessage remoteMessage),则系统托盘将接收消息并从通知栏读取正文和标题,并在通知栏中显示默认消息和标题。

  • FCM响应仅包含数据块:

在这种情况下,从json 删除通知

{
  
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

调用onMessageReceived()的解决方案

  1. 前景中的应用程序:

调用onMessageReceived(RemoteMessage remoteMessage),在通知栏中显示LargeIcon和BigPicture。我们可以从通知数据块中读取内容

  1. 后台应用程序:

调用onMessageReceived(RemoteMessage remoteMessage)时,系统托盘将不会收到消息,因为通知键不在响应中。在通知栏中显示LargeIcon和BigPicture

 private void sendNotification(Bitmap bitmap,  String title, String 
    message, PendingIntent resultPendingIntent) {

    NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
    style.bigPicture(bitmap);

    Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);

        notificationManager.createNotificationChannel(notificationChannel);
    }
    Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
            R.drawable.mdmlogo);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.mdmlogo)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSound)
            .setContentText(message)
            .setContentIntent(resultPendingIntent)
            .setStyle(style)
            .setLargeIcon(iconLarge)
            .setWhen(System.currentTimeMillis())
            .setPriority(Notification.PRIORITY_MAX)
            .setChannelId(NOTIFICATION_CHANNEL_ID);


    notificationManager.notify(1, notificationBuilder.build());


}

参考链接:

https://firebase.google.com/docs/cloud-messaging/android/receive


对于遭受后台问题的人们来说,最重要的部分是从服务器发送的JSON中删除“ notification”属性。这解决了问题。非常感谢。
Ramy M. Mousa

13

我有同样的问题。如果应用程序是前台,它将触发我的后台服务,在此我可以根据通知类型更新数据库。但是,该应用程序进入了后台-默认通知服务将受到注意,以向用户显示通知。

这是我的解决方案,用于在后台识别应用并触发您的后台服务,

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

在manifest.xml中

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

在最新的android 8.0版本中测试了此解决方案。谢谢


为什么要使用此FirebaseBackgroundService类?@Nagendra Badiganti

在哪里使用此代码公共类FirebaseBackgroundService扩展了WakefulBroadcastReceiver @Nagendra Badiganti

在您的包中创建一个服务类,并在manifest.xml中注册。确保您具有通知过滤器。由于服务会为每个GCM通知触发。
Nagendra Badiganti

firebase.google.com/docs/cloud-messaging/android/…我正在关注此链接,我需要添加此类以接收通知。只是从firebase的第一条消息发送消息..它说完成了,但是没有收到通知@Nagendra Badiganti

1
WakefulBroadcastReceiver自API级别26.1.0起不推荐使用。
Minoru

12

如果应用程序在后台模式或无效(杀死),以及您点击通知,您应该为您在LaunchScreen有效载荷(在我的情况下推出的屏幕是MainActivity.java)。

因此,在MainActivity.javaonCreate上检查Extras

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }

如何获得通知标题,正文和数据?
塔里库尔伊斯兰教

1
谢谢,这就是答案。@ Md.Tarikul Islam使用onMessageReceived()来解决此问题。
felixwcf

7

为我重写作品的handleIntent方法FirebaseMessageService

这是C#(Xamarin)中的代码

public override void HandleIntent(Intent intent)
{
    try
    {
        if (intent.Extras != null)
        {
            var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            foreach (string key in intent.Extras.KeySet())
            {
                builder.AddData(key, intent.Extras.Get(key).ToString());
            }

            this.OnMessageReceived(builder.Build());
        }
        else
        {
            base.HandleIntent(intent);
        }
    }
    catch (Exception)
    {
        base.HandleIntent(intent);
    }
}

那就是Java中的代码

public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }

            onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

handleIntent()是最终的
Ettore

@Ettore如何调用handleIntent函数?
Hiroto

从Firebase收到消息时将调用该方法,但是由于该方法被声明为final,因此无法覆盖该方法。(Firebase 11.6.0)
Ettore

5

默认情况下,当您的应用程序在后台运行并单击通知时,将启动您应用程序中的启动器活动,如果您的通知中包含任何数据部分,则可以按以下相同的活动进行处理,

if(getIntent().getExtras()! = null){
  //do your stuff
}else{
  //do that you normally do
}

如果我从mainActivity导航,如何导航回特定的Activity?
Mac_Play

@Uzair getIntent()。getExtras()始终为null,您还有其他解决方案吗?当应用程序免费运行时onMessageReceived方法未调用
user2025187

3

如果应用默认情况下在后台Fire-base中处理通知,但是如果我们要自定义通知,则必须更改服务器端,该服务器端负责发送自定义数据(数据有效负载)

从服务器请求中完全删除通知有效内容。仅发送数据并在onMessageReceived()中处理它,否则当应用程序在后台或被杀死时,不会触发您的onMessageReceived。

现在,您的服务器端代码格式如下所示:

{
  "collapse_key": "CHAT_MESSAGE_CONTACT",
  "data": {
    "loc_key": "CHAT_MESSAGE_CONTACT",
    "loc_args": ["John Doe", "Contact Exchange"],
    "text": "John Doe shared a contact in the group Contact Exchange",
    "custom": {
      "chat_id": 241233,
      "msg_id": 123
    },
    "badge": 1,
    "sound": "sound1.mp3",
    "mute": true
  }
}

注意:请参见上面的代码
“文本”中的这一行:数据有效负载中的“ John Doe在联系人交换组中共享了一个联系人”,您应该使用“文本”参数代替“正文”或“消息”参数来进行消息描述或其他操作想要使用文字。

onMessageReceived()

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getData().toString());

        if (remoteMessage == null)
            return;

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
           /* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
            Log.e(TAG, "Data Payload: " + remoteMessage);

            try {

                Map<String, String> params = remoteMessage.getData();
                JSONObject json = new JSONObject(params);
                Log.e("JSON_OBJECT", json.toString());


                Log.e(TAG, "onMessageReceived: " + json.toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }

2

只需在MainActivity的onCreate方法中调用此方法即可:

if (getIntent().getExtras() != null) {
           // Call your NotificationActivity here..
            Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
            startActivity(intent);
        }

如果我从mainActivity导航,如何导航回特定的Activity?
Mac_Play

2

根据t3h Exi的解决方案,我想在此处发布干净代码。只需将其放入MyFirebaseMessagingService中即可,如果应用程序处于后台模式,则一切正常。您至少需要编译com.google.firebase:firebase-messaging:10.2.1

 @Override
public void handleIntent(Intent intent)
{
    try
    {
        if (intent.getExtras() != null)
        {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            for (String key : intent.getExtras().keySet())
            {
                builder.addData(key, intent.getExtras().get(key).toString());
            }



           onMessageReceived(builder.build());
        }
        else
        {
            super.handleIntent(intent);
        }
    }
    catch (Exception e)
    {
        super.handleIntent(intent);
    }
}

我正在尝试实施您的解决方案,但是handleIntent()方法在我的SDK版本(SDK 27)中是最终的,因此我无法在服务中覆盖它……
matdev

是的,但是那不是我的错或给予-1的任何理由!很嚣张。直到Firebase 11.4.2生效,然后Google对其进行了更改(将此方法定为最终版本)。因此,现在您必须使用通知对自己的解决方案进行编程。
弗兰克(Frank)

我没有给-1但给了+1!
matdev

您保存了我的工作:P
amitabha2715 '18

2

试试这个:

public void handleIntent(Intent intent) {
    try {
        if (intent.getExtras() != null) {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
            for (String key : intent.getExtras().keySet()) {
            builder.addData(key, intent.getExtras().get(key).toString());
        }
            onMessageReceived(builder.build());
        } else {
            super.handleIntent(intent);
        }
    } catch (Exception e) {
        super.handleIntent(intent);
    }
}

在Firebase:11.8.0及更高版本中不再使用handleIntent。
Shihab Uddin '18年

1

我遇到了这个问题(如果应用程序在后台或关闭,则应用程序不希望在单击通知时打开),并且该问题click_action在通知正文中无效,请尝试将其删除或更改为有效的内容。


1

值得强调的一点是,即使应用程序在后台,您也必须使用数据消息(仅数据密钥)来获取onMessageReceived处理函数。您的有效负载中不应包含任何其他通知消息键,否则如果应用程序在后台运行,则处理程序将不会被触发。

在这里提到(但在FCM文档中没有强调):

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

使用您的应用服务器和FCM服务器API:设置数据密钥。可以是可折叠的或不可折叠的。


1

我正在使用的后端正在使用通知消息,而不是数据消息。因此,在阅读完所有答案之后,我尝试从启动的活动的意图包中检索额外内容。但是,无论我尝试从哪个键检索getIntent().getExtras();值,该值始终为null。

但是,我终于找到了一种使用通知消息发送数据的方法并从意图中检索。

此处的关键是将数据有效负载添加到Notification消息中。

例:

{
    "data": {
        "message": "message_body",
        "title": "message_title"
    },
    "notification": {
        "body": "test body",
        "title": "test title"
    },
    "to": "E4An.."
}

完成此操作后,您将可以通过以下方式获取信息:

intent.getExtras().getString("title") 将会 message_title

并且 intent.getExtras().getString("message")message_body

参考


1

如果您的问题与显示大图像有关,即您是从Firebase控制台发送带有图像的推送通知,并且仅在前台应用程序时才显示图像。解决此问题的方法是发送仅包含数据字段的推送消息。像这样:

{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }

您在“ AnotherActivity”之前输了逗号。我的android震动了,但实际上什么也没显示(没有文字,没有图像,没有推送)。
jekaby

1

当收到消息并且您的应用程序处于后台时,通知将发送到主要活动的额外意图。

您可以在主要活动的oncreate()或onresume()函数中检查额外的值。

您可以检查数据,表格等字段(通知中指定的字段)

例如我使用数据作为密钥发送

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}

0

我遇到了同样的问题,对此做了更多的研究。当应用程序在后台运行时,会向系统任务栏发送一条通知消息,但会将数据消息发送给onMessageReceived()
See https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3
https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

为了确保您发送的消息,文档说:“ 使用您的应用服务器和FCM服务器API:仅设置数据密钥。可以折叠或不可折叠。
请参阅https://firebase.google.com/ docs / cloud-messaging / concept-options#notifications_and_data_messages


0

消息有两种类型:通知消息和数据消息。如果仅发送数据消息,则消息字符串中没有通知对象。当您的应用在后台运行时会被调用。


0

检查@Mahesh Kavathiya的答案。就我而言,在服务器代码中只有这样:

{
"notification": {
  "body": "here is body",
  "title": "Title",
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

您需要更改为:

{
 "data": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
"notification": {
  "body": "here is body",
  "title": "Title"
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

然后,如果应用程序在后台运行,则默认活动意图额外将获得“数据”

祝好运!


-1

只需重写FirebaseMessagingService的OnCreate方法即可。当您的应用程序在后台运行时被调用:

public override void OnCreate()
{
    // your code
    base.OnCreate();
}

如果您可以添加说明并链接到一些文档,则此答案可能会更有用。您能告诉我们这对您有什么帮助吗?
kgkahn

@kilokahn你能告诉我你不明白什么吗?必须将所指示的方法插入到问题的代码中,并完全回答问题。该代码用于Xamarin,但是您可以简单地在java中进行转换。
Renzo Ciot18年

AFAIK官方文档(firebase.google.com/docs/cloud-messaging/android/client)并未讨论在扩展FirebaseMessagingService的服务中覆盖OnCreate的问题-如果您可以访问扩展文档,也许可以共享一个链接?另外,从您的答案中,还不清楚重写onCreate如何解决单击通知时无法调用onMessageReceived的问题-因此需要更多信息。
kgkahn

该文档没有提到OnCreate方法的替代,但是它可以工作,因为我在生产中使用了它。您想在onMessageReceived方法中插入的代码,显然可以用来执行一些后台操作的代码,可以在OnCreate上执行。
Renzo Ciot18年

在这种情况下,详细说明它对您有帮助的事实可能比列出解决方案更为有用。另外,未记录的行为很可能会随意停止使用更新,并且使用更新的人必须准备在更新时重新编写其代码。要放在本免责声明的需求。
kilokahn

-1

2种类型火力地堡推送通知:

1-通知消息(显示消息)->-1.1如果选择此变体,则当app在后台时,操作系统将自行创建一个通知,并将在中传递数据intent。然后由客户端来处理此数据。

- 1.2如果应用程序是在前台那么它将通过将收到通知callback-functionFirebaseMessagingService,它是由客户端处理它。

2-数据消息(最多4k数据)->这些消息用于(仅静默地)仅将数据发送到客户端,由客户端通过回调函数在两种情况下处理背景/前景数据 FirebaseMessagingService

这是根据官方文档:https : //firebase.google.com/docs/cloud-messaging/concept-options

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.