Home > OS >  How do you deserialise Firestore FieldValues in Android?
How do you deserialise Firestore FieldValues in Android?

Time:12-06

I have a Kotlin data class that effortlessly adds a Firebase Firestore server upload timestamp to an object when it's saved as a document to the Firestore database in the cloud.

All I have to do is add a FieldValue property to the Kotlin data class in the Android client, complete with the default value FieldValue.serverTimestamp() , and the object serialises to a Firestore document with the correct upload timestamp without any more effort from me:

data class CloudEntity(
  val uu: String = "",
  val de: String = "",
  ...
  val cr: Long = 0L,
  val ts: FieldValue = FieldValue.serverTimestamp() //server timestamp
)

But when I try to deserialise that Firestore document back to that exact same data class, using something like documentChange.document.toObject<CloudEntity>(), I get the error No properties to serialize found on class com.google.firebase.firestore.FieldValue.

So how do I deserialise that timestamp property?

I don't actually need that timestamp value on the client (it's only used in server-side queries), so I'd also be happy to implement a solution that doesn't actually deserialise the server timestamp value but simply discards the value and returns a zero value or something. Just as long as it doesn't crash the whole deserialisation.

thanks!

CodePudding user response:

I suggest you to create a separate object to retrieve from cloud but without that field! Something like this:

data class CloudEntity(
    val uu: String = "",
    val de: String = "",
    val cr: Long = 0L,
    val ts: FieldValue = FieldValue.serverTimestamp() //server timestamp
)

// Domain entity
data class Entity(
    val uu: String = "",
    val de: String = "",
    val cr: Long = 0L
)

// Mapper from domain to cloud
fun Entity.toCloud() = CloudEntity(uu, de, cr)

FieldValue.serverTimestamp() just returns a sentinel object that you use when writing a field to a document. It indicates the server should replace it with an actual Timestamp object. serverTimestamp() itself does not contain any date information, and you can't convert it to a date.

When you write the sentinel value to a document, and read it back out, it will become a Timestamp type object, which you can convert to a native Date object with its toDate() method, if you want to. You could add a 'val ts: Date' into the Entity class I wrote before, and then retrieve that value.

If you don't want to create that separate Entity without that field, you could remove that field from your CloudEntity class and add that field as an update to the document in your 'write' method.

  • Related