简体   繁体   English

如何解析Android中的Json数据for Firebase Cloud Messaging(FCM)

[英]How to parse Json data in android for Firebase Cloud Messaging (FCM)

i am using FCM for push messages and handling all incoming push notification in onMessageReceived. 我正在使用FCM进行推送消息并处理onMessageReceived中的所有传入推送通知。 Now the issue is with parsing nested json that comes inside this function remoteMessage.getData() 现在的问题是解析嵌套的json,它来自这个函数remoteMessage.getData()

I have following block coming as a push notification in device. 我有以下块作为设备中的推送通知。 content of data payload could be varied here it is dealer later on it can be productInfo 数据有效载荷的内容可以在这里改变,以后是经销商,它可以是productInfo

{
  "to": "/topics/DATA",
  "priority": "high",
  "data": {
    "type": 6,
    "dealerInfo": {
      "dealerId": "358",
      "operationCode": 2
    }
  }
}

this how i am parsing it 这是我如何解析它

 if(remoteMessage.getData()!=null){

        JSONObject object = null;
        try {
            object = new JSONObject(remoteMessage.getData());       

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


    }

now i am getting data with blackslashes as remoteMessage.getData() returns Map<String,String> so probably my nested block is being converted in string not sure though. 现在我正在使用blackslashes获取数据,因为remoteMessage.getData()返回Map<String,String>所以可能我的嵌套块正在转换为字符串,但不确定。

{
  "wasTapped": false,
  "dealerInfo": "{\"dealerId\":\"358\",\"operationCode\":2}",
  "type": "6"
}

and if i write object = new JSONObject(remoteMessage.getData().toString()); 如果我写object = new JSONObject(remoteMessage.getData().toString()); then it got failed with following notification 然后它通过以下通知失败了

{
  "to": "regid",
  "priority": "high",
  "notification" : {
      "body": "Message Body",
      "title" : "Call Status",
      "click_action":"FCM_PLUGIN_ACTIVITY"
   },
  "data": {
    "type": 1,
     "callNumber":"ICI17012702",
     "callTempId":"0",
      "body": "Message Body",
      "title" : "Call Status"
  }
}

error i get is 我得到的错误

> org.json.JSONException: Unterminated object at character 15 of
> {body=Message Body, type=1, title=Call Status, callNumber=ICI17012702,
> callTempId=0}

try this code: 试试这段代码:

public void onMessageReceived(RemoteMessage remoteMessage)
    {
        Log.e("DATA",remoteMessage.getData().toString());
        try
        {
            Map<String, String> params = remoteMessage.getData();
            JSONObject object = new JSONObject(params);
            Log.e("JSON OBJECT", object.toString());
            String callNumber = object.getString("callNumber");
            //rest of the code
      }
   }

Also make sure your JSON is valid use This 另外,还要确保您的JSON是有效的利用

Faced this issue when migrating from GCM to FCM. 从GCM迁移到FCM时遇到此问题。

The following is working for my use case (and OP payload), so perhaps it will work for others. 以下是我的用例(和OP有效负载),所以它可能适用于其他人。

JsonObject jsonObject = new JsonObject(); // com.google.gson.JsonObject
JsonParser jsonParser = new JsonParser(); // com.google.gson.JsonParser
Map<String, String> map = remoteMessage.getData();
String val;

for (String key : map.keySet()) {
    val = map.get(key);
    try {
        jsonObject.add(key, jsonParser.parse(val));
    } catch (Exception e) {
        jsonObject.addProperty(key, val);
    }
}

// Now you can traverse jsonObject, or use to populate a custom object:
// MyObj o = new Gson().fromJson(jsonObject, MyObj.class)

I have changed to 我改变了

JSONObject json = new JSONObject(remoteMessage.getData());

from

JSONObject json = new JSONObject(remoteMessage.getData().toString());

and work fine. 工作正常。

Since dealerInfo is parsed as string and not an object, create a new JSONObject with the string 由于dealerInfo被解析为字符串而不是对象,因此使用字符串创建新的JSONObject

JSONObject dealerInfo = new JSONObject(object.getString("dealerInfo"));
String dealerId = dealerInfo.getString("dealerId");
String operationCode = dealerInfo.getString("operationCode");

I didn't want to add GSON (as I use moshi) to make it working, so I made Kotlin method to form json string from remoteMessage's map, tested this on one example, so don't forget to test this implementation before using: 我不想添加GSON(因为我使用moshi)使它工作,所以我制作Kotlin方法从remoteMessage的地图形成json字符串,在一个例子上测试了这个,所以不要忘记在使用之前测试这个实现:

override fun onMessageReceived(remoteMessage: RemoteMessage?) {
        super.onMessageReceived(remoteMessage)

        var jsonString = "{"

        remoteMessage?.data?.let {
            val iterator = it.iterator()

            while (iterator.hasNext()) {
                val mapEntry = iterator.next()
                jsonString += "\"${mapEntry.key}\": "
                val value = mapEntry.value.replace("\\", "")
                if (isValueWithoutQuotes(value)) {
                    jsonString += value
                } else {
                    jsonString += "\"$value\""
                }

                if (iterator.hasNext()) {
                    jsonString += ", "
                }
            }
        }

        jsonString += "}"


        println(jsonString)
    }

    private fun isValueWithoutQuotes(value: String):Boolean{
       return (value == "true" || value == "false" || value.startsWith("[") || value.startsWith("{") || value == "null" || value.toIntOrNull() != null )
    }

Edit: 编辑:

Even better approach is to form FCM data like: 更好的方法是形成FCM数据,如:

notificationType: "here is ur notification type"
notificationData: {
//here goes ur data
}

That way we can retreive both values from map. 这样我们就可以从地图中检索这两个值。

remoteMessage?.data?.let {
    it["notificationData"]?.let {
         jsonString = it.replace("\\", "")
    }
}

We got clear json without "playing" around. 我们得到了清晰的json而没有“玩”。 And we can then use notificationType to convert json to the object that we need (as several notification data types can be passed sometimes) 然后我们可以使用notificationType将json转换为我们需要的对象(因为有时可以传递多个通知数据类型)

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

//            if (/* Check if data needs to be processed by long running job */ true) {
//                // For long-running tasks (10 seconds or more) use WorkManager.
//                scheduleJob();
//            } else {
//                // Handle message within 10 seconds
//                handleNow();
//            }

        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            sendNotification(remoteMessage.getNotification().getBody());
        }

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android,FireBase 云消息传递,(FCM) - Android, FireBase Cloud Messaging, (FCM) Android:订阅 Firebase 云消息传递 (FCM) 主题 - Android: Subscribe to Firebase Cloud Messaging(FCM) Topic Firebase Cloud Messaging(FCM)无法获取数据 - Firebase Cloud Messaging (FCM) not getting data 使用 FCM(Firebase 云消息传递)通过 C# 将推送发送到 Android - Send push to Android by C# using FCM (Firebase Cloud Messaging) Android Firebase Cloud Messaging(FCM):subscribeToTopic会自动重试吗? - Android Firebase Cloud Messaging(FCM): Will subscribeToTopic do automatic retries? Android Firebase 云消息传递令牌 (FCM) 令牌太短/不完整 - Android Firebase Cloud Messaging Token (FCM) token is too short/incomplete 在Android上实施FCM(Firebase Cloud Messaging)后,应用在启动时崩溃了吗? - App crashing on launch after the implementation of FCM(Firebase Cloud Messaging) on android? Firebase 云消息传递 (FCM) 不适用于低于 kitkat (4.4) 的 android 版本 - Firebase cloud messaging(FCM) not working on android version below kitkat (4.4) 如何防止Android显示来自FCM(Firebase云消息传递)的接收消息? - How do I prevent receive message from FCM (Firebase Cloud Messaging) being displayed by Android? 我们如何使用Firebase云消息传递(fcm)在Android中发送推送通知来发送图像和图标 - How we can send image and icon by using Firebase cloud messaging(fcm) for push notification in android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM