简体   繁体   中英

Firebase Firestore Swift, Timestamp but server time?

With Firestore, I add a timestamp field like this

    var ref: DocumentReference? = nil
    ref = Firestore.firestore()
        .collection("something")
        .addDocument(data: [
            "name": name,
            "words": words,
            "created": Timestamp(date: Date())
        ]) { ...
            let theNewId = ref!.documentID
            ...
    }

That's fine and works great, but it's not really correct. Should be using the "server timestamp" which Firestore supplies.

Please note this is on iOS (Swift) and Firestore, not Firebase.

What is the syntax to get a server timestamp?

The syntax you're looking for is:

"created": FieldValue.serverTimestamp()

This creates a token which itself has no date value. The value is assigned by the server when the write is actually written to the database, which could be much later if there are.network issues, so keep that in mind.

Also keep in mind that because they are tokens, they can present different values when you read them, to which we can configure how they should be interpreted:

doc.get("created", serverTimestampBehavior: .none)
doc.get("created", serverTimestampBehavior: .previous)
doc.get("created", serverTimestampBehavior: .estimate)

none will give you a nil value if the value hasn't yet been set by the server. For example, if you're writing a document that relies on latency-compensated returns, you'll get nil on that latency-compensated return until the server eventually executes the write.

previous will give you any previous values, if they exist.

estimate will give you a value, but it will be an estimate of what the value is likely to be. For example, if you're writing a document that relies on a latency-compensated returns, estimate will give you a date value on that latency-compensated return even though the server has yet to execute the write and set its value.

It is for these reasons that dealing with Firestore's timestamps may require handling more returns by your snapshot listeners (to update tokens). A Swift alternative to these tokens is the Unix timestamp:

extension Date {
    var unixTimestamp: Int {
        return Int(self.timeIntervalSince1970 * 1_000) // millisecond precision
    }
}

"created": Date().unixTimestamp

This is definitely the best explanation of how the timestamps work (written by the same Doug Stevenson who actually posted an answer): https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b

If you want a server timestamp for a field's value, use FieldValue.serverTimestamp() . This will return a token value that gets interpreted on the server after the write completes.

With Firestore, I add a timestamp field like this

    var ref: DocumentReference? = nil
    ref = Firestore.firestore()
        .collection("something")
        .addDocument(data: [
            "name": name,
            "words": words,
            "created": Timestamp(date: Date())
        ]) { ...
            let theNewId = ref!.documentID
            ...
    }

That's fine and works great, but it's not really correct. Should be using the "server timestamp" which Firestore supplies.

Please note this is on iOS (Swift) and Firestore, not Firebase.

What is the syntax to get a server timestamp?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM