18

When pulling data from Firestore, I use .toObject() to map the data received into my data class, which is:

data class Img(var event_uid: String = "", var isVip: Boolean = false , var nombre: String = "", var url: String = "")

However, the mapping is not doing well. I received the field isVip=>true in the task, but the object field is mapped as false (default value).

snapshot data

list of mapped object

What am I doing wrong?

EDIT: I see in Logcat

W/Firestore: (0.6.6-dev) [zzevb]: No setter/field for isVip found on class ***.model.Img

According to Kotlin Docu:

If the name of the property starts with is, a different name mapping rule is used: the name of the getter will be the same as the property name, and the name of the setter will be obtained by replacing is with set. For example, for a property isOpen, the getter will be called isOpen() and the setter will be called setOpen(). This rule applies for properties of any type, not just Boolean.

Maybe a Firestore with Kotlin issue?

MLavoie
  • 9,671
  • 41
  • 36
  • 56
lordneru
  • 700
  • 7
  • 19

2 Answers2

37

Try adding @field:JvmField to isValid boolean property.

TheTechWolf
  • 2,084
  • 2
  • 19
  • 24
  • To solve my issue, I took your solution. However, the proper way should be handle as @Alex Mamo [says](https://stackoverflow.com/a/52294033/9697465). – lordneru Sep 12 '18 at 20:31
  • 1
    How do you know about the `@field` attribute? It's not mentioned by the [`toObject`](https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/DocumentSnapshot#toObject(java.lang.Class)) documentation. Could you point me to where one can read more about it? Maybe there are more useful attributes. – t3chb0t Jun 27 '20 at 08:47
  • 1
    @t3chb0t `@field` is Kotlin annotation and it is not part of Firebase. `@JvmField` annotation does the trick here, and it says to Kotlin compiler that it should not create getters and setters of isValid property and that it should expose this property as a field. You can read more about `@field` and other annotation use site targets [here](https://kotlinlang.org/docs/reference/annotations.html?_ga=2.65505959.822283262.1593292835-1938789949.1575030406#annotation-use-site-targets). – TheTechWolf Jun 27 '20 at 21:37
9

If you are using in your model class a field named isVip which is of type Boolean, when instantiating an object of your Img class using the following line of code:

val img = Img("Y9X ... zYn", true, "Nombre", "https://...")

The way in which your isVip property will look like in your database will be simply: vip and not isVip as you probably expected. The resason that your isVip property is stored as isVip and not just vip is because you didn't add your data in the database using your helper class but somehow manually.

The reason you have that warning is because you have in your database a field which has no correspondent in your model class. In your model class you have a field named isVip which should have in the database a correspondent field named vip and not isVip, as it is now. So Firestore cannot create a connection between those fields and that's why you have that warning.

To solve this, you can remove (if is possible) the old data from your database and add fresh data using your model class. You need to have the name of your property in your model class named isVip and in your database just only vip.

Or you can change the name of your property in your modelc class from isVip to simply vip and that's it.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hello, your explanation is awesome, thanks for that. Make all sense. I added this fields when created the document in my Angular webapp and now using my Kotlin having this issue. I tried changing the property in Firestore and worked. However, I should change all my refenrences in my Angular app and that takes time, but probably is the correct solution. To solve my issue now, I took @TheTechWolf [solution](https://stackoverflow.com/a/52285505/9697465) – lordneru Sep 12 '18 at 20:29