Android: no se pudo deserializar el objeto. La clase no define un constructor sin argumentos. Si está utilizando ProGuard, asegú

CorePress2024-01-25  83

https://github.com/neuberfran/JThings/blob/main/app/src/main/java/neuberfran/com/jfran/model/FireFran.kt

Tengo este POJO arriba con el error mencionado en el tema. Sé que es un error ya mencionado aquí, pero he probado varias clases (además de esta) y no he tenido éxito, ya que mi modelo/clase POJO (e implementación de Código) es diferente de varias que vi:(Cada ayuda es bienvenido)

No se pudo deserializar el objeto. La clase no define un sin argumento constructor. Si está utilizando ProGuard, asegúrese de que estos constructores no se eliminan (se encuentran en el campo 'valor')

Cambio realizado en el documento del garaje, valor cambiado por valorb, etc...



------------------------------------

El error es muy claro, tu clase "FireFran" no tiene un constructor sin argumentos. Cuando intentas deserializar un objeto de Cloud Firestore, los SDK de Android requieren que la clase tenga un constructor predeterminado sin argumentos y también establece que se asigne a cada propiedad de la base de datos.

En Kotlin, las clases de datos no proporcionan un constructor predeterminado sin argumentos. Por lo tanto, de alguna manera necesita garantizar al compilador que todas las propiedades tengan un valor inicial. Puede proporcionar a todas las propiedades un valor inicial de nulo o cualquier otro valor que considere más apropiado.

Entonces tu "FireFran" podría verse así:

class FireFran(
    var alarmstate: Boolean  = false,
    var garagestate: Boolean = false,
    var id: String? = null,
    var userId: String? = null,
    var value: FireFranValue? = null //Newly added
) {
    //var value: FireFranValue = FireFranValue(false, 0)
    companion object Factory {
        fun create() :FireViewModel = FireViewModel()
        var COLLECTION = "device-configs"
        var DOCUMENT = "alarme"
        var FIELD_userId = "userId"
    }
}

Ahora, agregando las propiedades en el constructor, Kotlingenera automáticamente un constructor predeterminado sin argumentos. De esta forma, se podrá utilizar el SDK de Firebase para Android. También generará definidores para cada propiedad. Tenga en cuenta que cada propiedad es var y no val, y proporciona un valor nulo predeterminado en caso de "id" y "ID de usuario".

Si no realiza este cambio, no podrá utilizar la deserialización automática. Tendrás que leer el valor de cada propiedad del objeto DocumentSnapshot y pasarlos todos al constructor de Kotlin.

Editar:

En tu captura de pantalla, el "valor" La propiedad está en un objeto de tipo "FireFranValue", que tiene sólo dos propiedades, "brillo" y "encendido". Para poder leer los datos en "valor", su cuenta "FireFran" la clase debe coMantenga una nueva propiedad de tipo "FireFranValue". Por favor, consulte arriba de la clase.

Si no desea utilizar la deserialización automática, puede obtener el valor de cada propiedad individualmente. Por ejemplo, puede obtener el valor de "userId" propiedad usando el método getString (campo de cadena) de DocumentSnapshot:

 val userId = snapshot.getString("userId")

Edición2:

Tus tres clases deberían verse así:

class FireFran(
    var alarmstate: Boolean  = false,
    var garagestate: Boolean = false,
    var id: String? = null,
    var userId: String? = null,
    var owner: String? = null,
    var value: FireFranValue = FireFranValue(false),
    var valorb: FireFranValueB = FireFranValueB(openPercent = 0)
)
data class FireFranValue(
    var on: Boolean // = false
)

data class FireFranValueB(
    var openPercent: Number // = 0
)

Edición3:

class FireFran(
    var alarmstate: Boolean  = false,
    var garagestate: Boolean = false,
    var id: String? = null,
    var userId: String? = null,
    var owner: String? = null,
    var value: FireFranValue? = null,
    var valorb: FireFranValueB? = null
)
data class FireFranValue(
    var on: Boolean? = null
)

data class FireFranValueB(
    var openPercent: Number? = null
)

Ahora, "en" y "openPercent" obtendrá los valores de la base de datos.

Por favor, consulte la siguiente declaración de clase:

37

2

Sí, tanto FireFran como FireFranValue deben tener el constructor sin argumentos. Para el valor también debes agregar otra propiedad de tipo FireFranValue en la clase. ¿Funciona ahora?

- Alex Mamo

29/03/2021 a las 16:11

2

Por favor revise mi respuesta actualizada. ¿Está claro ahora?

- Alex Mamo

29 y 20 de marzo21 a las 18:37

2

Sí, en esa imagen veo un problema de nomenclatura de variables. Por lo tanto, los campos deben permanecer como "valor", tal como están en la base de datos, y cambiar el segundo. O simplemente comenta la línea 14. ¿Funciona ahora?

- Alex Mamo

30 de marzo de 2021 a las 6:31

3

YoNo estoy seguro de cómo se relacionan estos cambios con su pregunta inicial, pero la idea es tener el constructor sin argumentos para la clase y las clases internas. Mantenme informado.

- Alex Mamo

31 de marzo de 2021 a las 5:51

3

En ver. Por favor revise mi última edición (Editar3). ¿Funciona ahora?

- Alex Mamo

1 de abril de 2021 a las 14:36

------------------------------

Puedes definir un constructor sin argumentos en Kotlin de esta manera:

data class SampleClass(
    val field1: String,
    val field2: String
) {
    constructor(): this("", "")
}



------------------------------------

Lo primero: No fue necesario crear el campo (tipo de mapa) llamado valorb. Se resolvió con value.openPercent

Como tengo dos documentos (alarma y garagem) creé dos clases POJO (FireFran y FireFranB)

https://github.com/neuberfran/JThingsFinal/blob/main/app/src/main/java/neuberfran/com/jfran/model/FireFranB.kt

El secreto era tratar los campos value.on y value.openPercent como mapas (como lo son los hechos):

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare