Я получаю данные в формате JSON из уведомления FCM. Он имеет другой формат в зависимости от типов уведомлений, как показано ниже:
Формат 1: accept_request:
{
"alert": "Accept Request By driver",
"title": "Accept Request By driver",
"booking_id": "247",
"notification_type": "accept_request"
}
Формат 2: end_request:
{
"alert": "End trip By driver",
"title": "End trip By driver",
"booking_id": "247",
"notification_type": "end_request",
"servicesList": [
{
"service_id": "1",
"service_name": "Services1",
"status": "true",
"sub_category": [
{
"sub_cat_id": "1",
"sub_cat_name": "Doctors on call",
"service_cost": "15.00",
"service_cat_id": "1",
"cost": 0
}
],
"is_multiple_choose": "0",
"total_cost": 15
}
}
Я создал CommonNotificationBean.java как класс POJO. Я успешно проанализировал данные для accept_request.
Это работает, потому что все ключи имеют строковые значения и remoteMessage.getData() также возвращают значения типа Map<String, String>.
Код:
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("notification_type"));
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(object.toString()));
reader.setLenient(true);
CommonNotificationBean bean = gson.fromJson(reader, CommonNotificationBean.class);
sendNotification(bean);
}
Теперь я столкнулся с проблемой при анализе данных end_request, потому что он имеет вложенный массив JSON.
Что я могу сделать для динамических данных вместо Map<String, String>, потому что он не будет преобразовывать данные в тип Map<String, String>, поскольку он имеет некоторые значения типа List.
Кто-нибудь может помочь?
Просто оставьте комментарий, если в вопросе есть какая-либо ошибка, прежде чем проголосовать.
Я не уверен, что правильно понимаю эту проблему. У вас есть remoteMessage.getData(), который возвращает Map<String, String>. После этого вы конвертируете эту карту в JSON, используя JSONObject, который происходит от org.json. Наконец, вы десериализуете это JSON в CommonNotificationBean, используя Gson. Map<String, String> params = remoteMessage.getData(); линия дает некоторые проблемы - но в чем проблема? У вас есть исключение? Что такое тип remoteMessage? Как вы десериализовали этот входящий JSON в remoteMessage.getData()? Чтобы обрабатывать все значения, вам нужно определить карту как Map<String, Object>
Просто remoteMessage.getData() возвращает значения типа Map<String, String>, но иногда я получаю значения типа Map<String, List<String>>. Как я могу получить его и преобразовать в свой класс POJO.
Это просто, у вас должен быть абстрактный объект Notification с атрибутами alert, title и notification_type. А затем уже есть конкретные реализации, основанные на ваших возможных типах:
AcceptRequestNotification extends Notification только с int booking_id (это тот, который у вас уже есть, тот, который вы назвали CommonNotificationBean)EndRequestNotification extends Notification, который содержит, например, ArrayList с именем servicesList, этот ArrayList должен быть типа Service, а затем сервис будет иметь атрибуты: service_id, service_name, status, sub_category, который снова является другим ArrayList пользовательского типа.И затем вы просто меняете свой код на:
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("notification_type"));
Map<String, String> params = remoteMessage.getData();
JSONObject object = new JSONObject(params);
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(object.toString()));
reader.setLenient(true);
Class typeOf;
switch(remoteMessage.getData().get("notification_type")) {
case "accept_request":
typeOf = AcceptRequestNotification.class;
break;
case "end_request":
typeOf = EndRequestNotification.class;
break;
}
//you can cast this object later on (to the corresponding custom subclass of Notification), based on the notif.getNotificationType() value.
Notification notif = gson.fromJson(reader, typeOf);
sendNotification(notif);
}
Проблема, с которой я сталкиваюсь в этой строке: remoteMessage.getData();, потому что она не будет преобразовывать данные в тип Map<String, String>, поскольку у нее есть некоторые значения типа List.
Если вы отлаживаете значение remoteMessage.getData(), содержит ли карта ключ для servicesList? если да, то какова его стоимость? если нет, дает ли это вам какое-либо исключение?
Я получил ответ, как я отправил. Спасибо за уделенное время.
И, наконец, я получил решение, добавив несколько капель концепций. :)
У меня много проблем с преобразованием в JSON с правильным форматом, например:
и, наконец, следующий код работает для меня.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "remoteMessage.getData() : " + remoteMessage.getData());
// Map<String, String> stringStringMap = remoteMessage.getData();
JSONObject object = new JSONObject(remoteMessage.getData());
Log.d(TAG, "new JSONObject(remoteMessage.getData()) : " + object.toString());
String finalJSON = object.toString().replaceAll("\\\\", "").replace("\"[", "[").replace("]\"", "]");
Log.d(TAG, "Replace all back slash and invalid double quotes : " + finalJSON);
CommonNotificationBean bean = new Gson().fromJson(finalJSON, CommonNotificationBean.class);
sendNotification(bean);
}
Логкат:
удаленное сообщение.getData(): Получение данных без двойных кавычек.
remoteMessage.getData() : {content-available=1, notification_type=end_request, booking_id=247, priority=high, base_price=35, totalMinutePrice=1.5, alert=End trip By driver, sound=default, title=End trip By driver, total_amount=397, address_from=A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India, service_cost=360, servicesList=[{"total_cost":15,"sub_category":[{"cost":0,"sub_cat_name":"Doctors on call","sub_cat_id":"1","service_cost":"15.00","service_cat_id":"1"}],"service_name":"Services1","service_id":"1","is_multiple_choose":"0","status":"true"},{"total_cost":95,"sub_category":[{"cost":0,"sub_cat_name":"Hand","sub_cat_id":"3","service_cost":"20.00","service_cat_id":"2"},{"cost":0,"sub_cat_name":"Body","sub_cat_id":"4","service_cost":"75.00","service_cat_id":"2"}],"service_name":"Dressing","service_id":"2","is_multiple_choose":"1","status":"true"},{"total_cost":0,"sub_category":[{"cost":0,"sub_cat_name":"No","sub_cat_id":"7","service_cost":"0.00","service_cat_id":"3"}],"service_name":"Do you need oxygen?","service_id":"3","is_multiple_choose":"0","status":"true"},{"total_cost":30,"sub_category":[{"cost":0,"sub_cat_name":"Level 3","sub_cat_id":"10","service_cost":"30.00","service_cat_id":"4"}],"service_name":"Lift/Stairs Accessibility","service_id":"4","is_multiple_choose":"0","status":"true"},{"total_cost":220,"sub_category":[{"cost":0,"sub_cat_name":"Ventilator","sub_cat_id":"12","service_cost":"100.00","service_cat_id":"5"},{"cost":0,"sub_cat_name":"Intracenous (IV) drip","sub_cat_id":"13","service_cost":"120.00","service_cat_id":"5"}],"service_name":"Other Medical","service_id":"5","is_multiple_choose":"1","status":"true"},{}], tripdatetime=2019-03-27 10:57:51, address_to=19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India, notification_date_time=28-03-2019 17:24:09}
новый JSONObject(remoteMessage.getData()): преобразован в JSONObject, но получение нежелательной обратной косой черты и двойных кавычек
new JSONObject(remoteMessage.getData()) : {"content-available":"1","notification_type":"end_request","booking_id":"247","priority":"high","base_price":"35","totalMinutePrice":"1.5","alert":"End trip By driver","sound":"default","title":"End trip By driver","total_amount":"397","address_from":"A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India","service_cost":"360","servicesList":"[{\"total_cost\":15,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Doctors on call\",\"sub_cat_id\":\"1\",\"service_cost\":\"15.00\",\"service_cat_id\":\"1\"}],\"service_name\":\"Services1\",\"service_id\":\"1\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":95,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Hand\",\"sub_cat_id\":\"3\",\"service_cost\":\"20.00\",\"service_cat_id\":\"2\"},{\"cost\":0,\"sub_cat_name\":\"Body\",\"sub_cat_id\":\"4\",\"service_cost\":\"75.00\",\"service_cat_id\":\"2\"}],\"service_name\":\"Dressing\",\"service_id\":\"2\",\"is_multiple_choose\":\"1\",\"status\":\"true\"},{\"total_cost\":0,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"No\",\"sub_cat_id\":\"7\",\"service_cost\":\"0.00\",\"service_cat_id\":\"3\"}],\"service_name\":\"Do you need oxygen?\",\"service_id\":\"3\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":30,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Level 3\",\"sub_cat_id\":\"10\",\"service_cost\":\"30.00\",\"service_cat_id\":\"4\"}],\"service_name\":\"Lift\\/Stairs Accessibility\",\"service_id\":\"4\",\"is_multiple_choose\":\"0\",\"status\":\"true\"},{\"total_cost\":220,\"sub_category\":[{\"cost\":0,\"sub_cat_name\":\"Ventilator\",\"sub_cat_id\":\"12\",\"service_cost\":\"100.00\",\"service_cat_id\":\"5\"},{\"cost\":0,\"sub_cat_name\":\"Intracenous (IV) drip\",\"sub_cat_id\":\"13\",\"service_cost\":\"120.00\",\"service_cat_id\":\"5\"}],\"service_name\":\"Other Medical\",\"service_id\":\"5\",\"is_multiple_choose\":\"1\",\"status\":\"true\"},{}]","tripdatetime":"2019-03-27 10:57:51","address_to":"19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India","notification_date_time":"28-03-2019 17:24:09"}
Окончательный JSON:
Replace all back slash and invalid double quotes : {"content-available":"1","notification_type":"end_request","booking_id":"247","priority":"high","base_price":"35","totalMinutePrice":"1.5","alert":"End trip By driver","sound":"default","title":"End trip By driver","total_amount":"397","address_from":"A/ 4 forum bungalow Nr. Hicort, Sola, Ahmedabad, Gujarat 380015, India","service_cost":"360","servicesList":[{"total_cost":15,"sub_category":[{"cost":0,"sub_cat_name":"Doctors on call","sub_cat_id":"1","service_cost":"15.00","service_cat_id":"1"}],"service_name":"Services1","service_id":"1","is_multiple_choose":"0","status":"true"},{"total_cost":95,"sub_category":[{"cost":0,"sub_cat_name":"Hand","sub_cat_id":"3","service_cost":"20.00","service_cat_id":"2"},{"cost":0,"sub_cat_name":"Body","sub_cat_id":"4","service_cost":"75.00","service_cat_id":"2"}],"service_name":"Dressing","service_id":"2","is_multiple_choose":"1","status":"true"},{"total_cost":0,"sub_category":[{"cost":0,"sub_cat_name":"No","sub_cat_id":"7","service_cost":"0.00","service_cat_id":"3"}],"service_name":"Do you need oxygen?","service_id":"3","is_multiple_choose":"0","status":"true"},{"total_cost":30,"sub_category":[{"cost":0,"sub_cat_name":"Level 3","sub_cat_id":"10","service_cost":"30.00","service_cat_id":"4"}],"service_name":"Lift/Stairs Accessibility","service_id":"4","is_multiple_choose":"0","status":"true"},{"total_cost":220,"sub_category":[{"cost":0,"sub_cat_name":"Ventilator","sub_cat_id":"12","service_cost":"100.00","service_cat_id":"5"},{"cost":0,"sub_cat_name":"Intracenous (IV) drip","sub_cat_id":"13","service_cost":"120.00","service_cat_id":"5"}],"service_name":"Other Medical","service_id":"5","is_multiple_choose":"1","status":"true"},{}],"tripdatetime":"2019-03-27 10:57:51","address_to":"19/20, Chanakyapuri, Ahmedabad, Gujarat 382481, India","notification_date_time":"28-03-2019 17:24:09"}
Надеюсь, это поможет другим.
Тогда попробуйте этот метод: stackoverflow.com/a/22855546/4385913