这是我的舱单:

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

当前回答

你要工作onmessagerreceived (RemoteMessage RemoteMessage)在后台只发送数据部分通知部分这:

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"AnotherActivity": "True", "to": "设备id或设备令牌"

通过这个onMessageRecivied是调用后台和前台不需要处理通知使用通知托盘在你的启动器活动。 处理数据负载使用这个:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      

其他回答

我觉得所有的响应都是不完整的,但它们都有一些你需要处理的东西,当你的应用程序在后台时,一个有数据的通知。

遵循这些步骤,你将能够在应用程序处于后台时处理通知。

添加一个intent-filter,像这样: <活动android: name = "。MainActivity”> <意图过滤器> <行动android: name = "。MainActivity " / > <category android:name="android.intent.category. default " /> < /意图过滤器>

到要处理通知数据的活动。

以以下格式发送通知: { “通知”:{ "click_action": "。MainActivity”, "body": "new Symulti update !", "title": "新的Symulti更新!", "icon": "ic_notif_symulti"}, "data":{…}, "to": "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9"}

这里的关键是加法

"click_action" : ".MainActivity"

其中. mainactivity是您在步骤1中添加的带有intent-filter的活动。

从.MainActivity的onCreate中的通知中获取数据信息: onCreate(Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); //获取通知数据信息 Bundle Bundle = getIntent().getExtras(); If (bundle != null) { //bundle必须包含通知的"data"字段发送的所有信息 } }

这就是你需要做的。

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
}

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]

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

我想出了各种方案

当app在前台时, onMessageReceived()方法从FirebaseService调用。因此,服务类中定义的pendingIntent将被调用。

当app在后台时,第一个activity被调用。

现在,如果你使用了一个splashactivity,那么必须记住splashactivity会被调用,否则如果没有splashactivity,那么无论第一个activity是什么,都会被调用。

然后你需要检查firstActivity的getIntent(),看看它是否有任何bundle。如果一切正常,你会看到bundle在那里,值被填充。如果从服务器发送的数据标签中的值是这样的,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

然后在第一个活动中,你会看到, 有一个有效的意图(getIntent()不是null),有效的捆绑包和在捆绑包内,会有上面提到的以数据为键的整个JSON。

在这种情况下,提取值的代码是这样的,

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }

除了以上答案, 如果你正在使用FCM控制台测试推送通知,“data”键和对象没有添加到推送通知包。所以你不会收到详细的推送通知时,应用是后台或被杀。

在这种情况下,你必须选择你的后端管理控制台来测试应用程序的后台场景。

在这里,你将添加“data”键到你的推送包中。因此,详细的推送将如预期的那样显示出来。 希望这对少数人有帮助。