这是我的舱单:

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

当前回答

因为从Firebase通知UI发送的显示消息只在应用程序处于前台时有效。对于数据消息,需要对FCM进行POST调用

步骤

安装高级休息客户端谷歌Chrome扩展 添加以下头文件 关键字:Content-Type,值:application/json 密钥:授权,值:Key ="您的服务器密钥" 添加正文 如果使用主题: { "to": "/topics/topic_name", "数据":{ "key1": "value1", "key2": "value2", } } 如果使用注册id: { "registration_ids": "[{"id"},{id1}]", "数据":{ "key1": "value1", "key2": "value2", } }


它!。现在像往常一样收听onmessagerreceived回调。

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}

其他回答

自2019年以来,谷歌Firebase的api有了很大的变化 我的意思是: “com.google.firebase: firebase-messaging: 18.0.0”

在18.0.0中,他们删除了MyFirebaseInstanceIDService,你需要在MyFirebaseMessagingService中获取令牌,所以你只需要写:

@Override
public void onNewToken(String token) {
    Log.d(TAG, "Refreshed token: " + token);

}

在你的AndroidManifest.xml中,你必须删除:

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

此外,建议您设置默认值以自定义通知的外观。您可以指定自定义默认图标和自定义默认颜色,在通知有效负载中没有设置等效值时应用它们。

在应用程序标记中添加这些行来设置自定义默认图标和自定义颜色:

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_notification" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/push_channel" />

现在要在后台应用程序中处理通知消息,你应该在你的第一个Activity中定义一个Intent,即使它是SplashScreen。当你的应用程序在后台时,Android将通知消息定向到系统托盘。用户点击通知会默认打开应用启动器。

例如,如果你的Json是这样的:

 "data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

你只需要写一个简单的意图来获取这些值:

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");

根据firebase文档在发送下游使用firebase,有两种类型的有效载荷:

数据 此参数指定消息有效负载的自定义键-值对。 客户端应用程序负责处理数据消息。数据消息只有自定义键值对。 通知 此参数指定通知有效负载的预定义的、用户可见的键-值对。FCM自动代表客户端应用程序将消息显示给最终用户设备。通知消息具有一组预定义的用户可见键。

当你在前台时,你可以使用onmessagerecreceived()在FCM内部获取数据,你可以从数据有效载荷中获取数据。

data = remoteMessage.getData();
String customData = (String) data.get("customData");

当您在后台时,FCM将根据通知有效载荷的信息在系统托盘中显示通知。系统托盘上用于通知的标题、消息和图标都来自通知有效负载。

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

当你想在应用程序处于后台时自动在系统托盘上显示通知时,使用这个通知有效载荷。 当你的应用程序在后台运行时,为了获得通知数据,你应该在通知有效载荷中添加click_action。

如果你想打开你的应用并执行一个特定的动作(在后台),在通知有效载荷中设置click_action,并将其映射到你想要启动的Activity中的意图过滤器。例如,将click_action设置为OPEN_ACTIVITY_1来触发一个意图过滤器,如下所示:

<intent-filter>
  <action android:name="OPEN_ACTIVITY_1" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

把intent-filter放在你的清单上,在你的一个activity标签里面。当你点击通知时,它将打开应用程序并直接进入你在click_action中定义的活动,在本例中为“OPEN_ACTIVTY_1”。 在这个活动中,你可以通过以下方式获取数据:

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

我使用FCM为我的android应用程序和使用两个有效载荷。 下面是我使用的JSON示例:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification",
    "click_action" : "OPEN_ACTIVITY_1"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

我通过使用广播消息解决了这个问题。

创建一个Broadcast并从service worker中以Broadcast Message的形式发送有效负载。

然后在应用程序中接收有效负载并按您想要的方式处理它。

发送消息的简单方法,即使应用程序是在后台和前台如下:- 要使用API发送消息,您可以使用一个名为AdvancedREST客户端工具,它是一个chrome扩展,并发送带有以下参数的消息。

Rest客户端工具链接:https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

使用这个url:- https://fcm.googleapis.com/fcm/send 内容类型:application / json 授权:key=您的服务器密钥或授权密钥(参见下面的参考)

{ "data": {
    "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg",
    "message": "Firebase Push Message Using API"
    "AnotherActivity": "True"
     },
  "to" : "device id Or Device token"
}

授权密钥可以通过访问谷歌开发人员控制台,并单击项目左侧菜单上的凭证按钮来获得。在列出的API密钥中,服务器密钥将是您的授权密钥。

并且您需要将接收者的tokenID放在使用API发送的POST请求的“to”部分。

你要工作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());