这是我的舱单:

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

当前回答

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

不是每次调用它时,只有当应用程序是在前景

有一个覆盖方法,这个方法每次都会被调用,不管什么应用程序在前台,在后台或被杀死,但是这个方法在这个firebase API版本中可用

这是你必须从gradle导入的版本

compile 'com.google.firebase:firebase-messaging:10.2.1'

这就是方法

@Override
public void handleIntent(Intent intent) {
    super.handleIntent(intent);

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

在之前的firebase API中,这个方法是不存在的 当应用程序在后台....时,Fire base句柄本身现在你有了这个方法 无论你想做什么…你可以在这里用这个方法.....

如果您使用的是以前的版本,那么默认活动将启动 在这种情况下,你可以用同样的方法得到数据

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

//做你想做的事.... }

通常这是我们在通知中从服务器获得的结构

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

这是由你决定的,你想给数据键或者你想给任何你可以给.......的通知 无论你在这里给出什么,用相同的键,你都会得到数据.........

有少数情况下,如果你没有发送点击动作在这种情况下,当你将点击通知默认活动将打开,但如果你想打开你的特定活动时,应用程序是在后台,你可以从这个handleIntent方法调用你的活动,因为这是每次调用

其他回答

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
}

此情况仅用于firebase管理通知 如果应用程序在后台,则不会触发FirebaseMessagingService

要处理这种情况,请转到launcher activity,检查附加的intent bundle,并使用以下代码打印出所有数据:

 intent?.extras?.let {it->
        for (key in bundle.keySet()) {
            val value = bundle[key]
            Log.d("NotificationData", String.format("%s %s (%s)", key, value.toString(), value!!.javaClass.name))
        }
    }

显示所有数据类型的签入日志;

例子:

我想从通知中获得周和标题将使用这段代码

intent?.extras?.let {it->
        if (it.containsKey("week")){
            
        }
        if (it.containsKey("title")){

        }

我在firebase-messaging-sw.js中添加了以下代码,

messaging.onBackgroundmessage((payload)=>{
    console.log("background message detected!!");
    console.log("message : ", payload);
})

这是触发每次消息接收在后台。但我无法在主线程中使用有效负载,因为SW不支持它。所以我做了很多研究,在一个Android论坛上找到了一个解决方案。

因此,解决方案是必须从请求有效负载中删除通知有效负载。

所以我把有效载荷从

{
    "notification": {
        "title": "Hey there",
        "body": "Subscribe to AMAL MOHAN N youtube channel"
    },
    "to": "your-browser-token",
    "data": {
        "value1": "text",
        "value2": "",
        "value3": "sample3",
        "value4": "sample4"
    }
}

to

{
    "to": "your-browser-token",
    "data": {
            "value1": "text",
            "value2": "",
            "value3": "sample3",
            "value4": "sample4"
          }
}

有效负载的变化会自动在前台消息和后台消息中触发receiveMessage()。

我在一个Android论坛上发现了这个,这对我来说很有用!如果这对你有用,请告诉我。

在一般情况下

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

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

数据电文示例:

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

显示消息示例:

 {
     "notification": {
            "title" : "title",
            "body"  : "body text",
            "icon"  : "ic_notification",
            "click_action" : "OPEN_ACTIVITY_1"
        }
   }

Android端可以处理如下通知:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    …

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

    …

}

更多关于FCM的详细信息可以在这里找到:在Android上设置一个Firebase云消息客户端应用程序

我想出了各种方案

当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();
                }


            }
        }