我正在尝试将BigDecimal存储在Firebase中:
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)
我该如何储存?
答案 0 :(得分:1)
您可以创建以下代理:
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)
}
第一个BigDecimal
属性使用@get:Exclude
和@set:Exclude
进行注释,因此在序列化/反序列化期间Firebase会忽略它。
String
属性使用上面定义的委托。它没有支持字段,因此Firebase在序列化/反序列化此类时将使用String getAmount()
和setAmount(String amount)
方法。这些调用将委托给BigDecimalConverterDelegate
,BigDecimal
将直接从kotlin-reflect
属性设置或获取值。
请注意,您还必须包含compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
lib:
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() {
}
如果您想将它们与“kotlin-noarg”插件(https://youtrack.jetbrains.com/issue/KT-16692)一起使用,则委托人不会工作。空构造函数完全为空,并且代理未在那里初始化:
tools