[英]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.