如何在Firebase中存储BigDecimal?
我试图在Firebase中存储BigDecimal:
data class Money(val amount: BigDecimal = BigDecimal.ZERO, val currency: Currency = Currency.USD)
但是当把数据推送到数据库时,得到一个异常:
com.google.firebase.database.DatabaseException: Failed to parse node with class class java.math.BigDecimal at com.google.android.gms.internal.zzbpf.zza(Unknown Source) at com.google.android.gms.internal.zzbpf.zzar(Unknown Source) at com.google.android.gms.internal.zzbpf.zza(Unknown Source) at com.google.android.gms.internal.zzbpf.zzar(Unknown Source) at com.google.android.gms.internal.zzbpf.zza(Unknown Source) at com.google.firebase.database.DatabaseReference.zza(Unknown Source) at com.google.firebase.database.DatabaseReference.setValue(Unknown Source)
我怎样才能存储它?
您可以创建一个下面的委托:
class BigDecimalConverterDelegate(val bigDecimalProperty: KMutableProperty<BigDecimal>) { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return bigDecimalProperty.getter.call().toString() } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { bigDecimalProperty.setter.call(BigDecimal(value)) } }
然后你必须创建两个属性:
data class Money( @get:Exclude @set:Exclude var bigDecimalAmount: BigDecimal = BigDecimal.ZERO ) { var amount: String by BigDecimalConverterDelegate(this::bigDecimalAmount) }
首先使用@get:Exclude
和@set:Exclude
BigDecimal
属性进行注释,以便在序列化/反序列化过程中Firebase将忽略它。
String
属性使用上面定义的委托。 它没有后台字段,因此Firebase将在序列化/反序列化setAmount(String amount)
时使用String getAmount()
和setAmount(String amount)
方法。 这些调用将被委派给BigDecimalConverterDelegate
,它将直接从BigDecimal
属性设置或获取值。
请注意,您还必须包含kotlin-reflect
lib:
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
问题与kotlin-noarg
不幸的是,如果你想用“kotlin-noarg”插件( https://youtrack.jetbrains.com/issue/KT-16692 )来使用它们,代表们就不会工作。 空的构造函数完全是空的,代表不在这里初始化:
public Money(@NotNull BigDecimal bigDecimalAmount) { Intrinsics.checkParameterIsNotNull(bigDecimalAmount, "bigDecimalAmount"); super(); this.bigDecimalAmount = bigDecimalAmount; this.amount$delegate = new BigDecimalConverterDelegate((KMutableProperty)(new Money$amount$2(this))); } public Money() { }