如何在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() { }