Firebase Cloud Firestore: Запечатанные классы в пользовательских объектах в Kotlin Android - PullRequest
0 голосов
/ 09 января 2020

Я использую

implementation 'com.google.firebase:firebase-firestore:21.3.1'

для тестирования Firestore-Database SDK с Kotlin в версии 1.3.50.

Для тестов чтения / записи я создал простой класс данных :

data class Location(
    val uuid: String? = null,
    val name: String? = null
)

, который работает нормально и гладко, как и ожидалось.

Но если немного углубиться в расширение класса данных с помощью запечатанных классов Kotlin, это приводит к проблемам в сериализации. :

data class Location(
    val uuid: String? = null,
    val name: String? = null,
    val locationProperty: LocationProperty? = null
)

sealed class LocationProperty {

    data class TextProperty(
        val text: String? = null
    ) : LocationProperty()
}

Хотя запись в базу данных работает по-прежнему нормально, приложение генерирует исключение при сериализации результата:

document.toObject(Location::class.java)
java.lang.RuntimeException: No properties to serialize found
on class com.abc.def.LocationProperty

В интерфейсе Firestore я увидел, что мой запечатанный класс сохраняется как Map в базе данных № SQL, а необработанные данные полученных DocumentSnapshot выглядят следующим образом

(locationProperty =>ArraySortedMap{(text=>My entered text)}

, поэтому это может вызвать ошибку.

Есть ли способ решить эту проблему, возможно, предоставив специальный сериализатор при чтении или записи данных в Firestore, если это возможно?

1 Ответ

1 голос
/ 09 января 2020

Вы не сможете использовать запечатанный класс с toObject(). Это потому, что сами запечатанные классы не имеют достаточно информации, чтобы знать, какие свойства вы на самом деле хотите читать и писать. Только конкретные классы, которые подклассируют запечатанный класс, будут работать, поскольку отражение может использоваться для определения всех их свойств во время выполнения.

Сериализация объекта Firestore из отражения класса просто не подходит для этого конкретного случая использования , Вместо этого вы должны предоставить свои данные для сохранения как Map<String, *>. При чтении документа данные также будут отображаться аналогичным образом. Это потому, что Firestore внутренне конвертирует ваш объект в карту и обратно. Это будет включать в себя написание набора кода для чтения и записи записей этой карты с использованием свойств объекта, и это на самом деле вполне нормально.

В Firestore SDK в настоящее время нет концепции Плагин «сериализатор», который позволяет вам перехватывать сериализованные объекты для выполнения преобразования. Вы должны сериализовать карту, прежде чем писать документ, и десериализовать карту, читая документ обратно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...