我正在使用Firebase并测试在应用程序处于后台时从服务器发送通知到我的应用程序。通知发送成功,它甚至出现在设备的通知中心,但当通知出现或即使我点击它,我的FCMessagingService中的onmessagerreceived方法永远不会被调用。

当我测试这个,而我的应用程序是在前台,onmessagerreceived方法被调用,一切工作正常。问题发生在应用程序在后台运行时。

这是我有意为之的行为吗,或者我有办法解决这个问题吗?

这是我的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"));
        }
    }
}

当前回答

消息有两种类型:通知消息和数据消息。 如果你只发送数据消息,那就是在你的消息字符串中没有通知对象。它会在应用程序在后台时被调用。

其他回答

默认情况下,当你的应用程序在后台,你点击通知时,你的应用程序中的启动器活动将被启动,如果你的通知有任何数据部分,你可以在相同的活动中处理它,如下所示。

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

我现在回答这个问题可能有点晚了,但是官方文件有点混乱。

它还明确指出,有两种类型的通知

通知消息:由FCM自动处理 数据消息:由客户端应用程序处理。

毫无疑问,如果服务器发送了一个数据消息,那么onmessagerecreceived()方法肯定会被调用,但在通知消息的情况下,onmessagerecreceived()方法只会在应用程序在前台被调用,当应用程序在后台时,我们发送的数据只是null。

例子:

假设服务器正在发送通知消息类型:

A.对于前景:

remoteMessage。Data ["key"]可以工作

B.背景情况: -remoteMessage。Data ["key"]将返回null 但在这里,如果你在默认活动中发现相同的意图数据,getIntent().getExtras().getString("key")将工作

C.如发生灭杀: -remoteMessage。Data ["key"]将返回null 但在这里,如果你在默认活动中发现相同的意图数据,getIntent().getExtras().getString("key")将工作

现在,让我们假设服务器正在发送数据消息类型:

D.前景情况:

remoteMessage。Data ["key"]可以工作

E.背景情况:

remoteMessage。Data ["key"]可以工作

F.如果杀死:

remoteMessage。Data ["key"]可以工作

毫无疑问,数据消息将始终调用onmessagerreceived()方法,但在通知消息和应用程序处于后台/kill状态的情况下,您可以使用b的解决方案

我希望这会节省大家的时间。

如果应用程序在后台Fire-base默认处理通知,但如果我们想要我们的自定义通知,那么我们必须改变我们的服务器端,它负责发送我们的自定义数据(数据有效载荷)

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

现在,你的服务器端代码格式是这样的,

{
  "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
  }
}

注意:参见上面代码中的这一行 "text": "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());
            }
        }
    }

我也有类似的问题。根据本页中提到的答案和参考资料,以下是我如何用以下方法解决问题的两点意见:

我之前的消息格式如下:

    {
  "notification": {
    "title": "AppName",
    "sound": null,
    "body": "Hey!YouhaveaMessage"
  },
  "data": {
    "param1": null,
    "param2": [
      238
    ],
    "id": 1
  },
  "to": "--the device push token here--"
}

我修改了消息格式如下:

    {
  "data": {
    "title": "AppName",
    "body": "Hey! You have a message",
    "param1": null,
    "param2": [
      238
    ],
    "id": 1
  },
  "priority": "high",
  "to": " — device push token here — "
}

然后我从“data”负载本身检索标题、主体和所有参数。这解决了问题,然后我可以得到onmessagerreceived回调,即使应用程序是在后台。 我写了一篇博客文章解释了同样的问题,你可以在这里找到。

只需要重写FirebaseMessagingService的OnCreate方法。当你的应用程序在后台时被调用:

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