4

This is not retrofit but manual parsing in a Firebase message handler service. I am using KotlinJsonAdapterFactory() when building my Moshi instance.

For some reason it thinks one of the nodes is an array when I am asking for it to be parsed as an object. Here is the JSON:

[
{
    "$": {
        "updateOrigin": "CIS",
        "requestSource": "at20",
        "requestID": "0000000000004144"
    },
    "TS": [{
            "$": {
                "rid": "202008207681819",
                "uid": "L81819",
                "ssd": "2020-08-20"
            },
            "Location": [{
                    "$": {
                        "tpl": "PADTON",
                        "wtd": "17:28",
                        "ptd": "17:28"
                    },
                    "dep": [{
                            "$": {
                                "et": "17:28",
                                "src": "Darwin"
                            }
                        }
                    ],
                    "plat": [{
                            "_": "2",
                            "$": {
                                "platsup": "true",
                                "cisPlatsup": "true",
                                "platsrc": "M"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}
]

And here are my Data classes:

package com.cniekirk.traintimes.model
import com.squareup.moshi.Json

data class PushPortMessage(
    val pushPortMessageItems: List<PushPortMessageItem>?
)

data class PushPortMessageItem(
    @Json(name = "TS")
    val tS: List<TS>?,
    @Json(name = "$")
    val messageAttrs: MessageAttrs?
)

data class TS(
    @Json(name = "LateReason")
    val lateReason: List<String>?,
    @Json(name = "Location")
    val location: List<Location>?,
    @Json(name = "$")
    val tsAttrs: TSAttrs?
)

data class MessageAttrs(
    @Json(name = "updateOrigin")
    val updateOrigin: String?
)

data class Location(
    @Json(name = "arr")
    val arr: List<Arr>?,
    @Json(name = "dep")
    val dep: List<Dep>?,
    @Json(name = "pass")
    val pass: List<Pass>?,
    @Json(name = "plat")
    val plat: List<Plat>?,
    @Json(name = "$")
    val stationAttrs: StationAttrs?
)

data class TSAttrs(
    @Json(name = "rid")
    val rid: String?,
    @Json(name = "ssd")
    val ssd: String?,
    @Json(name = "uid")
    val uid: String?
)

data class Arr(
    @Json(name = "$")
    val arrPassAttrs: List<ArrPassAttrs>?
)

data class Dep(
    @Json(name = "$")
    var depAttrs: DepAttrs?
)

data class Pass(
    @Json(name = "$")
    val arrPassAttrs: ArrPassAttrs?
)

data class Plat(
    @Json(name = "_")
    val platform: Int?,
    @Json(name = "$")
    val platAttrs: PlatAttrs?
)

data class PlatAttrs(
    @Json(name = "platsup")
    val platsup: Boolean?,
    @Json(name = "cisPlatsup")
    val cisPlatsup: Boolean?
)

data class StationAttrs(
    @Json(name = "pta")
    val pta: String?,
    @Json(name = "ptd")
    val ptd: String?,
    @Json(name = "tpl")
    val tpl: String?,
    @Json(name = "wta")
    val wta: String?,
    @Json(name = "wtd")
    val wtd: String?,
    @Json(name = "wtp")
    val wtp: String?
)

data class ArrPassAttrs(
    @Json(name = "delayed")
    val delayed: String?,
    @Json(name = "et")
    val et: String?,
    @Json(name = "src")
    val src: String?
)

data class DepAttrs(
    @Json(name = "delayed")
    val delayed: String?,
    @Json(name = "et")
    val et: String?,
    @Json(name = "etUnknown")
    val etUnknown: String?,
    @Json(name = "etmin")
    val etmin: String?,
    @Json(name = "src")
    val src: String?
)

I may just be being stupid but I can't find the issue. Here is how I'm parsing the JSON:

val pushPortMessage = data["body"]
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

val pushPortAdapter = moshi.adapter(PushPortMessage::class.java)
pushPortMessage?.let {
    val msg = pushPortAdapter.fromJson(pushPortMessage)
    println(msg)
}
Charlie Niekirk
  • 1,015
  • 1
  • 10
  • 15

1 Answers1

5

you are parsing a list of objects not object so the parsing should be something like this

val pushPortMessage = data["body"]
val moshi = Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
val listType = Types.newParameterizedType(List::class.java, PushPortMessageItem::class.java)
val adapter: JsonAdapter<List<PushPortMessageItem>> = moshi.adapter(listType)
val pushPortMessageList = adapter.fromJson(pushPortMessage )
Mohammed Alaa
  • 3,140
  • 2
  • 19
  • 21
  • Thanks, figured this out about 5 mins after posting but you're absolutely correct – Charlie Niekirk Aug 20 '20 at 18:53
  • 1
    Thank you, after seeing your answer I realized I missed to notice that it was a list. In my case the changes were changing the return type of my API call – Meenohara Aug 21 '21 at 11:31