这是我的舱单:

<service android:name=".fcm.PshycoFirebaseMessagingServices">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<service android:name=".fcm.PshycoFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

当应用程序在后台和通知到达,然后默认通知来,不运行我的onmessagerreceived代码。

这是我的onMessageReceived代码。如果我的应用程序在前台运行,而不是在后台运行,就会调用这个函数。我怎么能运行这段代码时,应用程序是在后台太?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]

当前回答

2023年1月 对于那些实现了最新的Firebase云消息(FCM)的应用程序,您可能不会被限制在后台或完全关闭的情况下分别为应用程序发送数据和通知以处理数据。正如这里的一些回答所解释的那样,简短的版本是:

在你的启动器活动上,监视启动时的额外内容; 测试您的FCM数据中的唯一键是否在列表中; 如果存在,获取必要的数据并调用您的活动来处理您想要做的处理。

//Firebase
// [START handle_data_extras]
if (getIntent().getExtras() != null) {
    boolean fcmExtraFlag = false;
    for (String key : getIntent().getExtras().keySet()) {
        Object value = getIntent().getExtras().get(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("tracerId")){
            //test your known key to be sure it is from fcm
            //this must have come from notification (system) tray
            //this will come whether the app was in the background or completely off
            //generally, this could be in the main activity as it has the intent-filter already set
            fcmExtraFlag = true;
        }
    }
    //pick fcm values if present and notify and/or process accordingly
    //you may add time-lookup to ignore delayed (time-passed) ones; and ignore
    if(fcmExtraFlag){
        String tracerId = (String) getIntent().getExtras().get("tracerId"); 
        //prepare your data as needed
        String tracerData = tracerId+">"+data-one+">"+data-two;
        String msgBody = "This is a test notification; data received: "+tracerId;
        String fcmMessage = msgBody;
        //start your confirmation activity, directly or whichever way
        SidUtils.firebaseStartConfirms(msgBody, tracerData, this);
    }
}
// [END handle_data_extras]

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

其他回答

2023年1月 对于那些实现了最新的Firebase云消息(FCM)的应用程序,您可能不会被限制在后台或完全关闭的情况下分别为应用程序发送数据和通知以处理数据。正如这里的一些回答所解释的那样,简短的版本是:

在你的启动器活动上,监视启动时的额外内容; 测试您的FCM数据中的唯一键是否在列表中; 如果存在,获取必要的数据并调用您的活动来处理您想要做的处理。

//Firebase
// [START handle_data_extras]
if (getIntent().getExtras() != null) {
    boolean fcmExtraFlag = false;
    for (String key : getIntent().getExtras().keySet()) {
        Object value = getIntent().getExtras().get(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("tracerId")){
            //test your known key to be sure it is from fcm
            //this must have come from notification (system) tray
            //this will come whether the app was in the background or completely off
            //generally, this could be in the main activity as it has the intent-filter already set
            fcmExtraFlag = true;
        }
    }
    //pick fcm values if present and notify and/or process accordingly
    //you may add time-lookup to ignore delayed (time-passed) ones; and ignore
    if(fcmExtraFlag){
        String tracerId = (String) getIntent().getExtras().get("tracerId"); 
        //prepare your data as needed
        String tracerData = tracerId+">"+data-one+">"+data-two;
        String msgBody = "This is a test notification; data received: "+tracerId;
        String fcmMessage = msgBody;
        //start your confirmation activity, directly or whichever way
        SidUtils.firebaseStartConfirms(msgBody, tracerData, this);
    }
}
// [END handle_data_extras]

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

我也有同样的问题。经过一些挖掘为什么我的MainActivity被调用意图没有数据,我意识到我的发射器活动(如在Manifest)是SplashActivity。在那里我找到了消息数据,并将它们转发给MainActivity。效果很好。我相信这能帮助到一些人。

谢谢你的回答。

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

这是我从服务器发送的:

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

你可以像这样在onMessageReceived(RemoteMessage message)中接收你的数据(假设我需要获取id)

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

类似地,你可以在onmessagerecreceived()内从服务器获得任何数据。

像这样简单的总结

如果你的应用正在运行; onMessageReceived ()

是触发器。

如果你的应用程序没有运行(通过滑动杀死); onMessageReceived ()

不是直接触发和传递的。如果你有特殊的键值对。它们不工作,因为onmessagerecreceived()不工作。

我找到了这条路;

在你的启动器活动中,放入这样的逻辑,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

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

在这个例子中,我的键和值就像上面那样;(对不起,语言=))

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

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

有了这行代码,我关闭了我的应用程序,打开谷歌播放市场

快乐编码=)

1. 为什么会这样?

FCM (Firebase Cloud Messaging)中有两种类型的消息:

显示消息:这些消息仅在应用程序处于前台时触发onmessagerreceived()回调 数据消息:这些消息触发onmessagerreceived()回调,即使你的应用程序在前台/后台/被杀死

注意:Firebase团队还没有开发用于发送数据消息的UI 还有你的设备。您应该使用您的服务器发送这种类型!



2. 如何?

为了实现这一点,你必须对以下URL执行POST请求:

文章https://fcm.googleapis.com/fcm/send

关键字:Content-Type,值:application/json Key: Authorization, Value: Key =<your-server-key>

主体使用主题

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

或者如果你想把它发送到特定的设备

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}

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

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

这是你如何处理收到的消息:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}