I use Kotlin objects to work with Firebase database models, as described in the manual . I have many fields that are stored as strings, but are actually enumerations, so to be type safe, I have enumeration fields in models, as well as a row-delegated property that returns the firebase stored value (as suggested to the question I asked a while ago). Now these fields work if I get / set the line delegate in the code, but firebase libs seem to skip them when converting to / from the json database format.
A simple example:
abstract class BaseModel { @Exclude open var path: String? = null // fails even if I delete this field! } class Weight() : BaseModel() { constructor(v: Double, u: WeightUnit) : this() { value = v unitEnum = u } var value: Double = 0.0 @Exclude var unitEnum: WeightUnit = WeightUnit.KG var unit: String by EnumStringLowercaseConverter(WeightUnit::class.java).getDelegate(Weight::unitEnum) } [...] val testWeight = Weight(7.0, "kg") db.getReference("/valid/path/to/save/testWeight").setValue(testWeight) .addOnSuccessListener { r -> Log.d(LOG_TAG, "set successful") } .addOnFailureListener { e -> Log.e(LOG_TAG, "set error", e) }
setValue
always gives a Permission Denied
error, but it works if I remove the unitEnum
field and make unit
normal String
property.
This is like reading: Firebase does not give errors when receiving the Weight object, but the weightUnit
field weightUnit
never set to anything other than the default value. But if I manually do weight.unit = "lb"
, the unitEnum
field correctly returns WeightUnit.LB
.
I am using firebase libs v10.0.1
Now the questions are:
- What can I do to make delegated properties work correctly with firebase? I can try a different approach to delegated enumeration fields if the points from my original question are satisfied (readable, concise and type safe code).
- Is there a way to see how to accurately make firebase libs convert objects to / from json? Or at least see converted json? Maybe then I could change everything. Unfortunately, all firebase related events are displayed as
/* compiled code */
in AndroidStudio.
UPDATE : I could, of course, add the toMap()
method for each model, where I would build a map containing all the properties needed in firebase, but it would be tedious to do this for each model, and it solves the problem of saving enumeration fields still will not be installed upon receipt.
Delegated details are also skipped during serialization using GSON. Perhaps there is a general way to make delegated properties look like regular fields?
source share