关于Firebase:如何从Android中的FCM数据消息中获取价值?

How to get value from FCM data message in Android?

我正在尝试在我的应用中实施FCM通知。 我已经阅读了FCM数据消息类型,即使应用程序在后台,该消息类型也会收到通知,因此我试图在onMessageRecieved方法中实施该操作,从而得到如下所示的意外响应:

1
{title =2, message={"Status":"UNASSIGNED","CompanyName":"gd","LastModifiedDateTime":"2017-04-25 18:59:41","IsPartRequired":false,"ProblemCategory":"CONFIGURATION","IsGeneralClaim":false,"RegistrationID":1057,"IncidentCode":"INS\\/2017\\/04\\/25-0010","StatusID":0,"CreatedDateTime":"2017-04-25 18:59:41","IsInstallationCall":false}}

不知道如何解析此标题和消息中的单独值,让我发布我的firebase消息代码:

1
2
3
4
5
6
7
8
9
10
11
public class FireBaseMessage extends FirebaseMessagingService {
    private static final String TAG ="MyFirebaseMsgService";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      Map<String,String> data = remoteMessage.getData();
        Log.d(TAG,"From:" + data.toString());
//
}
}

在此日志消息中,正在得到这样的响应:如何从中获取价值,例如:

1
int title=data.get("title");

获取空指针,因为它的格式无效。 在我的服务器端,我试图发布这样的json格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "to":"es_OToDkj00:APA91bFqxbVMAaXy5fPtDbNVAkIwyVrPCmfGci2otHZPvdRoXPv-oDdjgtLR92Nqe8w6f57nCVceLbc3_zBWsInG9g1Pfdp3LvsMKyuaiYps0L1y3tn0N0XbzGseEI6jyiqs1r-sT9lb",
  "data":{
     "message":{
        "RegistrationID":1057,
        "IncidentCode":"INS/2017/04/25-0010",
        "CompanyName":"ABM INFOTECH",
        "StatusID":5,
        "Status":"ASSIGNED",
        "CreatedDateTime":"2017-04-25T12:03:45",
        "LastModifiedDateTime":"2017-04-25T18:59:41",
        "ProblemCategory":"CONFIGURATION",
        "IsPartRequired":false,
        "IsInstallationCall":false,
        "IsGeneralClaim":false
      },
     "title":"1"
   }

不知道我在哪里犯错。 谁能帮我? 提前致谢!


从邮件有效负载中获取标题:

用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {


    Log.d(TAG,"From:" + remoteMessage.getFrom());

    // Check if message contains a data payload.
    //In case when notification was send in"notification" parameter we need to check wheather data is null or not.
    if (remoteMessage.getData()!=null && remoteMessage.getData().size() > 0) {
        Log.d(TAG,"Message data payload:" + remoteMessage.getData());
        String title = remoteMessage.getData().get("title").toString();
    }


}

编辑

检查您的remoteMessage是否包含特定的密钥:

1
2
3
4
5
6
if (remoteMessage.getData()!=null){
 for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    Log.d(TAG,"key," + key +" value" + value);
}}


FCM消息有两种类型:

1)通知消息
2)数据信息

通知消息结构:

1
2
3
4
5
6
7
8
9
{
 "message":{
   "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "notification":{
     "title":"Portugal vs. Denmark",
     "body":"great match!"
    }
  }
}

In order to get data from the notification payload/messages:

1
2
3
4
5
6
7
8
9
  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (remoteMessage.getNotification() != null) {
           Log.d(TAG,"Message From" + remoteMessage.getFrom()); //sender ID
           Log.d(TAG,"Notification Title" + remoteMessage.getNotification().getTitle()); //notification title
           Log.d(TAG,"Notification Body" + remoteMessage.getNotification().getBody()); //notification body
        }
   }

数据消息结构:

1
2
3
4
5
6
7
8
9
10
{
 "message":{
   "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "data":{
     "Nick" :"Mario",
     "body" :"great match!",
     "Room" :"PortugalVSDenmark"
    }
  }
}

In order to get data from the data payload/messages:

1
2
3
4
5
6
7
8
@Override
 public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    if (remoteMessage.getData().size() > 0) {
       Log.d(TAG,"Data:" + remoteMessage.getData()); //Whole data
       Log.d(TAG,"Key Data :" +  remoteMessage.getData().get("key").toString()); //Get specific key data
    }
 }

经过多次搜索,我找到了这个答案,它工作完美

在以下情况下,使Firebase库调用onMessageReceived()

  • 前台应用
  • 后台应用
  • 应用程式已被杀死
  • 您不得在对Firebase API的请求中添加JSON密钥" notification",而应使用" data",请参见下文。

    当您的应用程序在后台或被终止时,以下消息将不会调用onMessageReceived(),并且您无法自定义通知。

    1
    2
    3
    4
    5
    6
    7
    8
    {
      "to":"/topics/journal",
      "notification": {
      "title" :"title",
      "text":"data!",
      "icon":"ic_notification"
        }
    }

    但是使用它会起作用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
     "to":"/topics/dev_journal",
      "data": {
          "text":"text",
          "title":"",
          "line1":"Journal",
          "line2":"刊物"
       }
    }

    基本上,消息与参数(作为Map)一起在参数RemoteMessage中与您的数据对象一起发送,然后您可以在onMessageReceived中管理通知,如代码段所示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
         Map<String, String> data = remoteMessage.getData();

         //you can get your text message here.
         String text= data.get("text");


         NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
            // optional, this is to make beautiful icon
                 .setLargeIcon(BitmapFactory.decodeResource(
                                        getResources(), R.mipmap.ic_launcher))  
            .setSmallIcon(smallIcon)  //mandatory
          .......
        /*You can read more on notification here:
        https://developer.android.com/training/notify-user/build-notification.html
        https://www.youtube.com/watch?v=-iog_fmm6mE
        */
    }

    参考:如何在Firebase中后台运行应用程序时处理通知


    您的"title"参数中有一个额外的空格字符:

    1
    "title":"1"

    很难看到,因为它只是一个空间。它应该是:

    1
    "title":"1"

    之所以会得到任何值,是因为从技术上讲,要发送的密钥是"title"(带空格),而在客户端代码中,您仅使用" title"(不带空格)。

    删除多余的空间后,您应该能够正确收到它。