我正在使用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"));
        }
    }
}

当前回答

根据Firebase云消息文档-如果Activity在前台,那么onmessagerecreceived将被调用。如果Activity处于后台或关闭,则通知消息将显示在应用程序启动器活动的通知中心。 你可以调用你的自定义活动点击通知,如果你的应用程序是在后台调用rest服务api为firebase消息:

URL-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>

其他回答

这个方法handleIntent()已经被贬低了,所以处理通知可以如下所示:

前台状态:点击通知将转到你在创建通知时提供的pending Intent的活动,因为它通常是用通知的数据负载创建的。 后台/已终止状态——在这里,系统本身根据通知有效负载创建了一个通知,点击该通知将带你到应用程序的启动器活动,在那里你可以轻松地获取任何生命周期方法中的Intent数据。

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

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

我也有同样的问题。使用“数据消息”而不是“通知”更容易。数据消息总是加载类onmessagerreceived。

在该类中,您可以使用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());
    }

下面是关于firebase消息的更清晰的概念。我从他们的支援组找到的。

Firebase有三种消息类型:

通知消息:通知消息工作在后台或前台。当app在后台时,通知消息被传递到系统托盘。如果应用程序在前台,消息由onmessagerreceived()或didReceiveRemoteNotification回调处理。这些实质上就是所谓的显示消息。

数据消息:在Android平台上,数据消息可以工作在后台和前台。数据消息将由onMessageReceived()处理。在Android上,数据有效载荷可以在用于启动你的活动的Intent中检索。具体来说,如果你有"click_action":"launch_Activity_1",你只能通过getIntent()从Activity_1中检索这个意图。

Messages with both notification and data payloads: When in the background, apps receive the notification payload in the notification tray, and only handle the data payload when the user taps on the notification. When in the foreground, your app receives a message object with both payloads available. Secondly, the click_action parameter is often used in notification payload and not in data payload. If used inside data payload, this parameter would be treated as custom key-value pair and therefore you would need to implement custom logic for it to work as intended.

另外,我建议您使用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消息的更清晰的概念。我从他们的支援组找到的。

欲了解更多信息,请访问我的这个线程和这个线程

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

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

这是我从服务器发送的

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

所以你可以在onMessageReceived(RemoteMessage message)中接收你的数据,就像这个....假设我需要得到id

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