如何在Firebase中存储BigDecimal?

时间:2017-03-23 01:25:17

标签: android firebase firebase-realtime-database kotlin

我正在尝试将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)

我该如何储存?

1 个答案:

答案 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)方法。这些调用将委托给BigDecimalConverterDelegateBigDecimal将直接从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

的问题

如果您想将它们与“kotlin-noarg”插件(https://youtrack.jetbrains.com/issue/KT-16692)一起使用,则委托人不会工作。空构造函数完全为空,并且代理未在那里初始化:

tools