Android Kotlin在Firebase数据库中保存数据类

时间:2018-10-28 12:55:52

标签: android firebase firebase-realtime-database kotlin

我正在Kotlin上开发一个集成了Firebase的Android应用程序。 现在,我想将数据(Kotlin data class)存储到Firebase数据库中。

数据类:

@Parcelize
data class Trip(
    val fromAddress: String,
    val toAddress: String,
    val fromLocation: String,
    val toLocation: String,
    val orderUid: String
) : Parcelable

@Parcelize
data class Order(val trip: Trip, val date: Date, var status: OrderStatus, val userUid: String) : Parcelable {
    var pickUpDate: Date? = null
    var dropOffDate: Date? = null
    var price: Double? = null

}

Fireabase数据库写操作:

fun createNewOrder(
    fromAddress: String,
    toAddress: String,
    fromLocation: Location,
    toLocation: Location
) {
    val fromGeoLocation = fromLocation.convertToGeoLocation()
    val toGeoLocation = toLocation.convertToGeoLocation()
    val userUid = sharedPreferences[CURRENT_USER_UID_KEY, ""]!!
    val orderKey = databaseReference.child(DB_ORDERS_KEY).push().key
    val tripKey = databaseReference.child(DB_TRIPS_KEY).push().key
    val trip = orderKey?.let { createNewTrip(fromAddress, toAddress, it) }
    val order = trip?.let { Order(it, Date(), OrderStatus.PENDING, userUid) }

    if (trip != null && order != null && !userUid.isNullOrEmpty()) {
        ordersGeoFire.setLocation(trip.fromGeoLocation, fromGeoLocation)
        ordersGeoFire.setLocation(trip.toGeoLocation, toGeoLocation)
        val allData = mutableMapOf<String, Any>()
        allData["/$DB_TRIPS_KEY/$tripKey"] = trip?.convertToMap()
        allData["/$DB_ORDERS_KEY/$orderKey"] = order?.convertToMap()
        allData["/$DB_USERS_KEY/$userUid/$DB_ORDERS_KEY/$orderKey"] = true
        databaseReference.updateChildren(allData)
    }
}

我收到此错误:

  

com.google.firebase.database.DatabaseException:类kotlin.Unit上找不到要序列化的属性

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您的代码中的问题是Trip类中的字段未初始化。建议的创建模型类的方法是:

class Trip(
        val displayName: String = "",
        val email: String = "",
        val photoUrl: String = "",
        val userId: String = ""
)

这只是您所需要的。创建Trip类的新对象的方法是:

val trip = Trip(displayName, email, photoUrl, userId)

答案 1 :(得分:0)

这是我的错误,因为我忘记在扩展return type函数中添加convertToMap。现在他们看起来像这样:

fun Trip.convertToMap(): MutableMap<String, Any> {
    val map = mutableMapOf<String, Any>()
    map["fromAddress"] = fromAddress
    map["toAddress"] = toAddress
    map["fromGeoLocation"] = fromGeoLocation
    map["toGeoLocation"] = toGeoLocation
    map["orderUid"] = orderUid
    return map
}

还要感谢@Alex Mamo的回答,这对我的调查很有帮助。

现在我的代码看起来像这样并且可以正常工作:

@Parcelize
data class Trip(
    var fromAddress: String = "",
    var toAddress: String = "",
    var fromGeoLocation: String = "",
    var toGeoLocation: String = "",
    var orderUid: String = ""
) : Parcelable

@Parcelize
data class Order(
    var trip: Trip? = null,
    var date: Date? = null,
    var status: OrderStatus? = null,
    var userUid: String = ""
) : Parcelable {
    var pickUpDate: Date? = null
    var dropOffDate: Date? = null
    var price: Double? = null
}

fun createNewOrder(
    fromAddress: String,
    toAddress: String,
    fromLocation: Location,
    toLocation: Location
): LiveData<Order> {
    orderLiveData = MutableLiveData()
    orderLiveData.value = null
    val userUid = sharedPreferences[CURRENT_USER_UID_KEY, ""]!!
    val orderKey = databaseReference.child(DB_ORDERS_KEY).push().key
    val tripKey = databaseReference.child(DB_TRIPS_KEY).push().key
    val trip = orderKey?.let { createNewTrip(fromAddress, toAddress, fromLocation, toLocation, it) }
    val order = trip?.let { Order(it, Date(), OrderStatus.PENDING, userUid) }

    if (trip != null && order != null && !userUid.isNullOrEmpty()) {
        val allData = mutableMapOf<String, Any>()
        allData["/$DB_TRIPS_KEY/$tripKey"] = trip.convertToMap()
        allData["/$DB_ORDERS_KEY/$orderKey"] = order.convertToMap()
        allData["/$DB_USERS_KEY/$userUid/$DB_ORDERS_KEY/$orderKey"] = true
        databaseReference.updateChildren(allData) { databaseError, databaseReference ->
            if (databaseError == null) orderLiveData.value = order
        }
    }

    return orderLiveData
}

希望这会有所帮助