Ad

How Do I Handle Reads And Writes Of Objects Containing A Server Timestamp In Firebase?

I'll explain. I've been stuck with figuring out how to handle timestamps in Firebase using FieldValue.serverTimestamp().

So let's assume I have an object called question, and I want the object to contain server stamped timestamp. Is how the class should look like (the timestamp part is the only important part):

class Question(
    val id: String,
    val title: String,
    val details: String,
    val author_ID: String,
    val timestamp: FieldValue,
) {
    constructor() : this(
        "",
        "",
        "",
        "",
        FieldValue.serverTimestamp()
    )
}

And then I'll set it like this?

val mQuestion = Question("id", "title", "details", "author", FieldValue.serverTimestamp())

db.collection("questions").document().set(mQuestion)

Is this the correct way to go?

If so, how do I handle the read? Because when the data is being read, the time stamp field would now correspond to a Date type and would cause a crash because Date can't be converted to FieldValue.

Do I need to have two classes for each type of object? One used for reading and one for writing? It doesn't feel right.

I was thinking also maybe I have the timestamp in the class be of type Data and then I upload it empty, and a cloud function would write the date immediately. I feel like this might work but also doesn't feel efficient.

Ad

Answer

The automatic serialization and deserialization is mostly (from my perspective) a convenience for common read and write operations. I don't see it as a one-size-fits-all mechanism for all reads and writes that could be performed. BOTTOM LINE: If the convenience layer doesn't work for you, then don't use it.

What you're trying to do with FieldValue.serverTimestamp() seems like one of the outlying cases where convenience is not met, since that value has to be determined on the server and not on the client. As it's implemented, the client and server can't agree on a specific type that applies to both reads and writes. If the client wants the server to write a current timestamp, it has to send a token to indicate that, not an actual typed timestamp.

You could certainly implement different types for reading and writing, and that's OK. Or, you can take control of the serialization by passing and parsing Map values, which would probably be more common (and more efficient, as it doesn't involve reflection). In short, I don't think there is an easy way out with the currently strongly typed system.

Ad
source: stackoverflow.com
Ad