firebase db:具有 Kotlin 委托属性的模型

     2023-04-19     149

关键词:

【中文标题】firebase db:具有 Kotlin 委托属性的模型【英文标题】:firebase db: models with Kotlin delegated properties 【发布时间】:2017-08-01 22:14:13 【问题描述】:

我正在使用 Kotlin 对象来处理我的 Firebase 数据库模型,如 in the guide 所述。我有很多存储为字符串的字段,但实际上是枚举,所以为了类型安全,我在模型中有枚举字段,加上一个返回 firebase 存储值的字符串委托属性(如前段时间a question I asked 中所建议的那样)。现在,如果我在代码中获取/设置字符串委托,这些字段就可以工作,但是在转换到/从数据库的 json 格式转换时,firebase 库似乎会跳过它们。

一个简单的例子:

abstract class BaseModel 
    @Exclude
    open var path: String? = null  // fails even if I delete this field!


class Weight() : BaseModel() 
    constructor(v: Double, u: WeightUnit) : this() 
        value = v
        unitEnum = u
    

    var value: Double = 0.0
    @Exclude
    var unitEnum: WeightUnit = WeightUnit.KG
    var unit: String by EnumStringLowercaseConverter(WeightUnit::class.java).getDelegate(Weight::unitEnum)



[...]
val testWeight = Weight(7.0, "kg")
db.getReference("/valid/path/to/save/testWeight").setValue(testWeight)
            .addOnSuccessListener  r -> Log.d(LOG_TAG, "set successful") 
            .addOnFailureListener  e -> Log.e(LOG_TAG, "set error", e) 

setValue 总是给出 Permission Denied 错误,但如果我删除 unitEnum 字段并将 unit 设置为正常的 String 属性,则可以正常工作。

读取时类似:Firebase 在获取 Weight 对象时没有给出错误,但 weightUnit 字段从未设置为默认值以外的任何值。但是,如果我手动执行weight.unit = "lb"unitEnum 字段会正确返回WeightUnit.LB

我正在使用 firebase 库 v10.0.1

现在,问题:

如何使委派属性与 Firebase 一起正常工作?只要满足my original question 中的点(可读、简洁和类型安全的代码),我就可以尝试对委托枚举字段使用不同的方法。 有什么方法可以了解 Firebase 库如何准确将对象转换为 json 或从 json 转换对象?或者至少看到转换后的 json?也许那时我可以自己调整一些东西。不幸的是,所有与 firebase 相关的内容在 AndroidStudio 中都显示为 /* compiled code */

更新:我当然可以为每个模型添加一个 toMap() 方法,在其中我将构建一个包含 firebase 所需的所有属性的地图,但对每个模型都这样做会很烦人模型,并且只解决了保存问题,获取时仍然不会设置枚举字段。

使用 GSON 序列化时也会跳过委托的道具。那么也许有一种通用的方法可以使委托属性看起来像常规字段?

【问题讨论】:

GSON 不允许序列化函数,以及委托的扩展 getter/setter。一种可能的解决方案是让 unitEnum 成为一个委托,它在更新时也会更新单位字符串。 var unitEnum: WeightUnit by EnumStringUpdate(WeightUnit::class.java).getDelegate(Weight::unit) ::class.java 已弃用,请使用 .javaClass 【参考方案1】:

试试这个代码,它应该可以工作。

@get:Exclude @set:Exclude
var unitEnum: WeightUnit = WeightUnit.KG
var unit: String
    get() = unitEnum.name
    set(v)  unitEnum = WeightUnit.valueOf(v) 

【讨论】:

这是显而易见的解决方案,我知道这会起作用,但请看一下我上面链接的上一个问题,关于我为什么不想这样做:) ***.com/questions/41651507/… 简而言之: (1)我的枚举字段不能像您发布的那样直接转换,(2)我有很多这些字段并且不想重复代码,(3)我有比简单枚举更复杂的字段要转换. @quezak 我会坚持使用@StringDef 注释,只是讨厌枚举(:另外,考虑创建方法toMap()fromMap(),而不是使用内置的firebase 方法进行序列化/反序列化跨度> 是的,我现在正在研究适合我情况的通用toMap()fromMap()。优点是模型类中没有双重字段。缺点可能是整个模型需要在读/写时进行转换,而不仅仅是枚举字段——但现在我的模型足够小,这不应该成为问题。 (无论如何,firebase 可能会进行一些处理,具有类似的复杂性)

如何从 Firebase android kotlin 获取所有具有特定价值的孩子?

】如何从Firebaseandroidkotlin获取所有具有特定价值的孩子?【英文标题】:howtogetallchildwithspecificvaluefromFirebaseandroidkotlin?【发布时间】:2021-05-3005:33:32【问题描述】:我想从我的数据库中的所有用户那里获取图像中的颜色项。我试... 查看详情

kotlin委托的本质以及mmkv的应用(代码片段)

...代理、代购、中介等方式间接去购买,这样我们也有具有了购买该东西的能力。那代码怎么实现呢?首先我们定义一个接口,声明一个购买方法:interfaceSubjectfunbuy()然后创建一个代理类实现该购买功能:classDel... 查看详情

kotlin委托必须重视的几个点(代码片段)

委托模式是实现继承的一个很好的替代方式,也是Kotlin语言的一种特性,可以很优雅的实现委托模式。在开发过程中也少不了使用它,但常常都会被低估。所以今天就让它得到重视,去充分的掌握kotlin委托特性以... 查看详情

具有存储到 firebase db 的实时更新的 JSON API

】具有存储到firebasedb的实时更新的JSONAPI【英文标题】:JSONAPIwithliveupdatesstoredtofirebasedb【发布时间】:2018-02-0407:39:44【问题描述】:正如标题所示,我有一个每隔几秒更新一次的JSONAPI。我想将该JSON添加到我的Firebase数据库中,... 查看详情

Firebase:在 Kotlin/Java 中使用枚举字段的干净方式?

】Firebase:在Kotlin/Java中使用枚举字段的干净方式?【英文标题】:Firebase:cleanwayforusingenumfieldsinKotlin/Java?【发布时间】:2017-05-2919:44:54【问题描述】:我在firebase上的数据使用了许多具有字符串类型的字段,但实际上是枚举值(... 查看详情

kotlin委托

...请求,接受请求的对象将请求委托给另一个对象来处理。Kotlin直接支持委托模式,更加优雅,简洁。Kotlin通过关键字by实现委托。类委托类的委托即一个类中定义的方法实际是调用另一个类的对象的方法来实现的。以下实例中派... 查看详情

kotlin对象枚举委托(代码片段)

目录一、Kotlin对象1.kotlin伴生对象2.kotlin对象和单例模式二、Kotlin枚举1.kotlin定义枚举2.kotlin使用枚举三、Kotlin委托1.kotlin类委托2.kotlin属性委托3.kotlinMap委托4.kotlin延迟属性5.kotlin属性监听附Github源码一、Kotlin对象1.kotlin伴生对象clas... 查看详情

kotlin委托

...明白 两点核心:1.委托:就是A的活交给B来做2.函数在kotlin中就是普通类型,它的声明形式:(x:type,...)->type 这里给出demo,局部委托属性局部委托属性:就是可以将局部变量当作属性来对待,于是就可以对这个局部属性... 查看详情

深入kotlin-委托(代码片段)

委托委托不是java中的概念。它仅仅是一种设计模式,但是kotlin从语言层级上,通过by关键字提供了对委托模式的支持。类委托interfaceMyInteface//1 funmyPrint()classMyInterfaceImpl(valname:String):MyInterface//2 overridefunmyPring() println(name) 查看详情

kotlin委托(代码片段)

1、类委托类的委托是一个类中定义的方法实际是调用另一个类的对象的方法来实现的。interfaceIDemofunaction1()funaction2()//被委托的类classDemoImpl:IDemooverridefunaction1()println("doaction1")overridefunaction2()println("doaction2")/ 查看详情

kotlin委托(代码片段)

1、类委托类的委托是一个类中定义的方法实际是调用另一个类的对象的方法来实现的。interfaceIDemofunaction1()funaction2()//被委托的类classDemoImpl:IDemooverridefunaction1()println("doaction1")overridefunaction2()println("doaction2")/ 查看详情

kotlin委托(代码片段)

1、类委托类的委托是一个类中定义的方法实际是调用另一个类的对象的方法来实现的。interfaceIDemofunaction1()funaction2()//被委托的类classDemoImpl:IDemooverridefunaction1()println("doaction1")overridefunaction2()println("doaction2")/ 查看详情

kotlin学习之委托机制(代码片段)

类的委托    委托模式可以很好的替代实现继承,kotlin本身支持需要零样板代码,一个类Derived可以继承Base并委托它所有的public方法到一个指定的类:interfaceBasefunprint()classBaseImpl(valx:Int):Baseoverridefunprint()print(x)classDerived(b:B... 查看详情

kotlin委托工厂map存储属性值(代码片段)

1.委托工厂(1)概念?委托工厂顾名思义:生产委托对象的工厂类。(2)定义?该类实现了operator修饰的provideDelegate方法,返回ReadWriteProperty/ReadOnlyProperty,该类就可提供对应类型的委托对象。/***委托工厂类(生产委托对象)*/classP... 查看详情

Kotlin 和 Firebase 读写数据

】Kotlin和Firebase读写数据【英文标题】:KotlinandFirebasereadandwritedata【发布时间】:2020-07-0820:02:52【问题描述】:我已经学习了3周的Kotlin,所以我想从我的Firebase数据库中读取数据。这是写入数据的MainActivity.kt。valdatabase=Firebase.data... 查看详情

Firebase 到 Kotlin 片段

】Firebase到Kotlin片段【英文标题】:FirebasetoKotlinFragment【发布时间】:2021-11-1716:32:11【问题描述】:有没有办法将Firebase中的选定数据检索到Kotlin中的片段?并非所有数据都只选择行。我是Kotlin的新手。请帮帮我。首先用户登录... 查看详情

Firebase @Exclude 与 kotlin 数据类

】Firebase@Exclude与kotlin数据类【英文标题】:Firebase@Excludewithkotlindataclass【发布时间】:2017-02-2804:47:32【问题描述】:我在Kotlin中有这个数据类(示例):importcom.google.firebase.database.ExcludedataclassUser(valname:String="",@Excludevalage:Int=0)而... 查看详情

kotlin委托必须重视的几个点(代码片段)

委托模式是实现继承的一个很好的替代方式,也是Kotlin语言的一种特性,可以很优雅的实现委托模式。在开发过程中也少不了使用它,但常常都会被低估。所以今天就让它得到重视,去充分的掌握kotlin委托特性以... 查看详情