Why use server timestamp?
The local datetime could be inaccurate (device accidentally change to wrong timezone, time not syncing with external server for long time or intentional change of clock time).
If we use a local time, it could be a future date by accident. Imagine we sort by using local date in descending order, the future date object will always show up first (imagined the future date is one year ahead).
Server Timestamp offer reliable sorting on server-side.
Why don't use server timestamp
Server timestamp require access to backend server, which doesn't work when the device is offline.
If you sort by server timestamp when the device if offline, the date shall be null and the sort order is unpredictable.
Local timestamp is required for offline sorting on client side.
Firestore Server Timestamp
Insert server timestamp via FieldValue.serverTimestamp().
val db = FirebaseFirestore.getInstance()db.collection("test") .add(mapOf( "created" to FieldValue.serverTimestamp(), "posted_date" to Timestamp.now() )) .addOnSuccessListener { val id = it.id it.get().addOnSuccessListener { document -> val id = document.id val created = document.getDate("created") val postedDate = document.getDate("posted_date") Timber.d("id=$id, created=$created, postedDate=$postedDate") } }
id=euvr10lwtinNT66xJBxB, created=Fri Mar 01 18:29:58 GMT+08:00 2019, postedDate=Fri Mar 01 18:29:58 GMT+08:00 2019
Insert server timestamp via @ServerTimestamp using custom POJO object.
class Test( @get:PropertyName(CREATED) @set:PropertyName(CREATED) @ServerTimestamp var created: Timestamp? = null, @get:PropertyName(POSTED_DATE) @set:PropertyName(POSTED_DATE) var postedDate: Timestamp? = Timestamp.now()) { companion object { const val COLLECTION_NAME = "test" const val CREATED = "created" const val POSTED_DATE = "posted_date" }}
val db = FirebaseFirestore.getInstance()val item = Test()db.collection(Test.COLLECTION_NAME) .add(item) .addOnSuccessListener { val id = it.id it.get().addOnSuccessListener { document -> val item = document.toObject(Test::class.java) val id = document.id if (item != null) { val created = item.created?.toDate() val postedDate = item.postedDate?.toDate() Timber.d("id=$id, created=$created, postedDate=$postedDate") } } }
id=6CCqsILuj9MOcAZGoXBh, created=Fri Mar 01 18:41:39 GMT+08:00 2019, postedDate=Fri Mar 01 18:41:39 GMT+08:00 2019
NOTE: when device is offline, addOnSuccessListener
would not be called, and server timestamp shall be null. Refer to Firestore Offline Behaviour