6

I am using firebase and this is my data class definition:

data class ClaimOrder(val address: String? = null,
                  val amount: Long = 0L,
                  val isProcessed: Boolean = false,
                  val onCreate: kotlin.Any? = ServerValue.TIMESTAMP)

however on logs I am seeing following warning: W/ClassMapper: No setter/field for isProcessed found on class com.guness.bitfarm.service.models.ClaimOrder

I have tried @SerializedName("isProcessed") but no luck.

guness
  • 6,336
  • 7
  • 59
  • 88
  • 1
    `val` is used to declare read-only property. You have to use `var` to provide setter for that property. – BakaWaii Aug 16 '17 at 18:09
  • @BakaWaii also tried that, interestingly I am seeing only for `isProcessed` – guness Aug 16 '17 at 18:11
  • Oh, see if this [post](https://stackoverflow.com/questions/37481017/kotlin-view-setenabled-function-missing) is related. – BakaWaii Aug 16 '17 at 18:17
  • @BakaWaii could be related, found what is wrong, variable name `isProcessed` is wrong. probably underlying gson and kotlin generates/expects different names. when I use `processed` in both kotlin and firebase, problem seems resolved. – guness Aug 16 '17 at 18:21

3 Answers3

10

I can't find any official document from Firebase mentioning about the naming rules of the getter and setter, but it seems like they are looking for JavaBean-like getters/setters

When you have a property named isProcessed, Firebase requires you to have getter/setter named getIsProcessed()/setIsProcessed(). However, a different naming rule is applied when the property is start with is in Kotlin. It genarates getter/setter named isProcessed()/setProcessed(), according to Kotlin doc:

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.

guness
  • 6,336
  • 7
  • 59
  • 88
BakaWaii
  • 6,732
  • 4
  • 29
  • 41
4

I don't know the exact reason but here is my guess:

variable name isProcessed causes different accessor methods to be generated so underlying gson and kotlin methods does not match.

however using just processed seems to fix things well.

guness
  • 6,336
  • 7
  • 59
  • 88
0

For some reason even if I left out the is in front of the variable name it still wouldn't parse. Instead I solved it by just making a custom constructor like so:

data class User(
    var uid: String? = null,
    var isDeveloper: Boolean? = null,
    var email: String? = null
) {
    constructor(dict: Map<String, Any>) : this() {
        this.uid = dict["uid"] as? String
        this.isDeveloper = dict["isDeveloper"] as? Boolean
        this.email = dict["email"] as? String
    }
}

Which I parsed like so:

documentSnapshot.data?.let {
    completion(User(it), null)
    return@addOnSuccessListener
}

Although it's probably not the best solution if you need a massive constructor but for small data classes it works fine :)

Robin
  • 704
  • 8
  • 24