android - 如何在 Firebase 中存储 BigDecimal?

标签 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)

如何存储它?

最佳答案

您可以创建以下委托(delegate):

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 属性使用上面定义的委托(delegate)。它没有支持字段,因此 Firebase 在序列化/反序列化此类时将使用 String getAmount()setAmount(String amount) 方法。这些调用将委托(delegate)给 BigDecimalConverterDelegate,它将直接从 BigDecimal 属性设置或获取值。

请注意,您还必须包含 kotlin-reflect 库:

compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

kotlin-noarg 问题

不幸的是,如果您想将委托(delegate)与“kotlin-noarg”插件( https://youtrack.jetbrains.com/issue/KT-16692 )一起使用,它们将无法工作。空的构造函数完全是空的,并且委托(delegate)没有在那里初始化:

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

关于android - 如何在 Firebase 中存储 BigDecimal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42965598/

相关文章:

android - 在用户同意的情况下在 Android 中禁用蓝牙

android - 在 Android Studio 2.2 的开发者服务中看不到云选项

java.lang.ClassCastException : java. util.ArrayList 无法转换为 Firebase 实时数据库中的 java.util.Map

即使在用户通过身份验证后,Android 默认 Firebase 权限也被拒绝

java - OnEditorActionListener 中的 NullPointerException

java - 当我们在 firebase 中引用一个不存在的 child 时会发生什么?

android - 在 ImageView 上滚动 ScrollView

css - 我应该安装什么才能让我的 Firebase 系统识别 ="btn btn-action hide"类? (我假设这是一个定制的 CSS 类?)

javascript - 等待查询实时更新然后返回值 [Vuex ,Firestore]

javascript - Firebase 实时数据库在实际构建中无法在 Ionic iOS 上运行,但可以在实时重新加载中运行