Как анализировать данные Json в android для Firebase Cloud Messaging (FCM) [дубликат]
этот вопрос уже есть ответ здесь:
Я использую FCM
для push-сообщений и обработки всех входящих push-уведомлений в onMessageReceived. Теперь проблема заключается в разборе вложенного json, который входит в эту функцию remoteMessage.getData()
у меня есть следующий блок в качестве push-уведомления в устройстве. содержание полезной нагрузки данных может быть изменено здесь это дилер позже это может быть productInfo
{
"to": "/topics/DATA",
"priority": "high",
"data": {
"type": 6,
"dealerInfo": {
"dealerId": "358",
"operationCode": 2
}
}
}
вот как я разбираю это
if(remoteMessage.getData()!=null){
JSONObject object = null;
try {
object = new JSONObject(remoteMessage.getData());
} catch (JSONException e) {
e.printStackTrace();
}
}
Я получаю данные с blackslashes как remoteMessage.getData()
возвращает Map<String,String>
так что, вероятно, мой вложенный блок преобразуется в строку, но не уверен.
{
"wasTapped": false,
"dealerInfo": "{"dealerId":"358","operationCode":2}",
"type": "6"
}
а если я напишу object = new JSONObject(remoteMessage.getData().toString());
потом стало не с уведомление
{
"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"
}
}
меня
> org.json.JSONException: Unterminated object at character 15 of
> {body=Message Body, type=1, title=Call Status, callNumber=ICI17012702,
> callTempId=0}
5 ответов
попробуйте этот код:
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
}
}
также убедитесь, что ваш JSON действителен use этой
столкнулся с этой проблемой при миграции из GCM в FCM.
следующее работает для моего варианта использования (и полезной нагрузки 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)
С dealerInfo
анализируется как строка, а не объект, создайте новый JSONObject со строкой
JSONObject dealerInfo = new JSONObject(object.getString("dealerInfo"));
String dealerId = dealerInfo.getString("dealerId");
String operationCode = dealerInfo.getString("operationCode");
Я изменил на
JSONObject json = new JSONObject(remoteMessage.getData());
С
JSONObject json = new JSONObject(remoteMessage.getData().toString());
и работать нормально.
Я не хотел добавлять GSON (поскольку я использую moshi), чтобы он работал, поэтому я сделал метод Kotlin для формирования строки json из карты remoteMessage, протестировал это на одном примере, поэтому не забудьте проверить эту реализацию перед использованием:
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:
еще лучший подход заключается в формировании данных FCM, таких как:
notificationType: "here is ur notification type"
notificationData: {
//here goes ur data
}
таким образом, мы можем восстановить оба значения с карты.
remoteMessage?.data?.let {
it["notificationData"]?.let {
jsonString = it.replace("\", "")
}
}
мы получили ясно json без "играть" вокруг.
И мы можем использовать notificationType
чтобы преобразовать json в объект, который нам нужен (так как иногда могут передаваться несколько типов данных уведомлений)