我正在使用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推送通知有两种类型:

1-通知消息(显示消息)-> . 0 如果你选择这个变体,如果app在后台,操作系统会自己创建一个通知,并在intent中传递数据。然后由客户端来处理这些数据。

如果应用程序在前台,那么通知将通过FirebaseMessagingService中的回调函数接收,并由客户端来处理。

2-数据消息(最多4k数据)->这些消息只用于发送数据到客户端(静默),这是由客户端来处理这两种情况下后台/前台通过FirebaseMessagingService的回调函数

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

其他回答

如果应用程序处于后台模式或非活动(被杀死),你点击通知,你应该在启动屏幕中检查有效载荷(在我的情况下,启动屏幕是MainActivity.java)。

在onCreate的mainactivity。java中检查Extras:

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

根据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>

我也有同样的问题,在这方面做了更多的研究。当应用程序在后台时,通知消息被发送到系统托盘,但数据消息被发送到onmessagerreceived () 看到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

从服务器请求中完全删除通知字段。只发送数据并在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());
        }

我也有同样的问题。使用“数据消息”而不是“通知”更容易。数据消息总是加载类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());
    }