1
votes

I'm having issues pasing a Snapshot from the Firebase Realtime Database into a Data Class in Kotlin using ProGuard.

Here's how the data looks in the Firebase console:

Firebase realtime database, screenshot of data

Here's how I've modeled that data class In my android app:

data class PickupCode(
    val code: String,
    val boxId: String,
    val orderId: String,
    val suborderId: String,
    val drawers: List<Int>,
    val isDelivered: Boolean
) {
    constructor(): this("", "", "","", emptyList(), false)

    override fun toString(): String {
        return code
    }
}

Here's how I build the database request:

val reference = database.getReference("pickupCodes/$boxId/$code")

val listener = object : ValueEventListener {
    override fun onDataChange(snapshot: DataSnapshot) {
        if (snapshot.exists()) {
            println(snapshot)
            val pickupCode = snapshot.getValue<PickupCode>(PickupCode::class.java)
            pickupCode?.let {
                println("Code: ${it.code}, is delivered: ${it.isDelivered} to drawers: ${it.drawers.toString()}")
                if (!it.isDelivered) {
                    // No success
                } else {
                    // Success!
                }
            } ?: run {
                // No success
            }
        } else {
            // No success
        }
    }

    override fun onCancelled(error: DatabaseError) {
        // No success
    }
}

This is what the println(snapshot) line prints:

DataSnapshot { key = 320625, value = {isDelivered=true, code=320625, drawers={0=2}, orderId=-LhdzXS4-gyT0ysNe-zi, suborderId=-LhdzYhT78y9b3iJcyrb, boxId=box_1} }

And this is what the next print 3 lines lates prints:

Code: 320625, is delivered: false to drawers: [2]

Here I would expect is delivered to be true, but for some reason true-value of isDelivered from the snapshot, is ignored when parsing the snapshot into a PickupCode-class. The value isDelivered of the PickupCode, is equal to the empty constructor of the class.

But WHY and HOW to fix?

All the other values from the snapshot gets parsed corrently. I'm new to Android, but I have a hunch that ProGuard (whatever that is) has some of the blame here.. Here's how I've set it up:

-keepattributes Signature

-keepclassmembers class PickupCode.** {
    *;
}
1
What's the value of isDelivered in println("Code: ${it.code}, is delivered: ${it.isDelivered} to drawers: ${it.drawers.toString()}")? The same as in the println(snapshot)?Alex Mamo
Nope :/ That's the one mentioned in the quote below. It's false..Wiingaard
But if you try print it.isDelivered outside the pickupCode?.let block, what is the value?Alex Mamo
I found a solution, see below :)Wiingaard
Good to hear that :) I answered a similar question here.Alex Mamo

1 Answers

1
votes

I found a solution to this.. When inspecting the verbose logs I found this:

W/ClassMapper: No setter/field for isDelivered found on class com.x.y.models.PickupCode

After playing a bit around, I found that for some weird reason, the setters for properties starting with is are ignored :S I tested with other property names as well and types.. fx. val isBerp: Number gets the same warning.

So after changing the property name from isDelivered to delivered in both the class and firebase, it works..

I wasn't able to find documentation for this behaviour, so if someone knows about it, it would appreciate a link..