Can you get the timestamp from a Firebase array key?

后端 未结 2 1798
旧巷少年郎
旧巷少年郎 2020-12-01 18:40

According to this blog post, firebase array keys are created using a timestamp:

It does this by assigning a permanent, unique id based on the current

相关标签:
2条回答
  • 2020-12-01 18:53

    Here's a version of Frank's code re-written in Swift (4.2 at the time of writing.)

    Just to be clear, my use case for this was to patch my old models with no timestamps (createdAt, updatedAt.) I could just throw in random dates in them just to save me some headaches. But then that wouldn't be relevant to their models. I knew that there's an element of time baked into these auto-ids based on what I've read from other articles.

    let PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
    
    func decode(autoId: String) -> TimeInterval {
      let substring = autoId.substring(toIndex: 8)
      var timestamp = 0
      for i in 0..<substring.length {
        let c = Character(substring[i])
        timestamp = (timestamp * 64) + PUSH_CHARS.firstIndex(of: c)!.encodedOffset
      }
      return TimeInterval(exactly: timestamp)!
    }
    

    Grab the Playground-ready code here: https://gist.github.com/mkval/501c03cbb66cef12728ed1a19f8713f7.

    0 讨论(0)
  • 2020-12-01 19:08

    As I said in my comment, you should not rely on decoding the timestamp from the generated id. Instead of that, you should simply store it in a property in your Firebase.

    That said, it turns out to be fairly easy to get the timestamp back:

    // DO NOT USE THIS CODE IN PRODUCTION AS IT DEPENDS ON AN INTERNAL 
    // IMPLEMENTATION DETAIL OF FIREBASE
    var PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
    function decode(id) {
      id = id.substring(0,8);
      var timestamp = 0;
      for (var i=0; i < id.length; i++) {
        var c = id.charAt(i);
        timestamp = timestamp * 64 + PUSH_CHARS.indexOf(c);
      }
      return timestamp;
    }
    var key = prompt("Enter Firebase push ID");
    if (key) {
      var timestamp = decode(key);
      console.log(timestamp+"\n"+new Date(timestamp));
      alert(timestamp+"\n"+new Date(timestamp));
    }

    I'll repeat my comment, just in case somebody thinks it is a good idea to use this code for anything else than as an exercise in reverse engineering:

    Even if you know how to retrieve the timestamp from the key, it would be a bad idea to do this in production code. The timestamp is used to generate a unique, chronologically ordered sequence. If somebody at Firebase figures out a more efficient way (whichever subjective definition of efficiency they happen to choose) to accomplish the same goal, they might change the algorithm for push. If your code needs a timestamp, you should add the timestamp to your data; not depend on it being part of your key.

    Update

    Firebase documented the algorithm behind Firebase push IDs. But the above advice remains: don't use this as an alternative to storing the date.

    0 讨论(0)
提交回复
热议问题