【问题标题】:Can you get the timestamp from a Firebase realtime database key?您可以从 Firebase 实时数据库密钥中获取时间戳吗?
【发布时间】:2015-03-10 14:13:19
【问题描述】:

根据这个blog post,firebase 数组键是使用时间戳创建的:

它通过根据当前时间戳(与服务器时间相匹配的偏移量)分配一个永久的、唯一的 id 来做到这一点。

在给定密钥的情况下,有没有办法恢复此时间戳以供以后使用?

【问题讨论】:

  • 即使您可以从密钥中检索时间戳,这也是一个坏主意。时间戳用于生成唯一的、按时间顺序排列的序列。如果 Firebase 的某个人找到了一种更有效的方法(无论他们碰巧选择了哪种主观的效率定义)来实现相同的目标,他们可能会更改 push 的算法。如果您的代码需要时间戳,则应将时间戳添加到数据中;不依赖于它成为您密钥的一部分。
  • 如果你喜欢逆向工程:push Id是从NextPushId这里cdn.firebase.com/js/client/2.1.0/firebase-debug.js的时间戳生成的(你可以搜索“NextPushId = function”快速找到它。

标签: firebase firebase-realtime-database


【解决方案1】:

正如我在评论中所说,您不应依赖从生成的 id 解码时间戳。相反,您应该将其简单地存储在 Firebase 中的属性中。

也就是说,要取回时间戳是相当容易的:

// 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));
}

我将重复我的评论,以防有人认为将此代码用于除逆向工程练习之外的其他任何事情是个好主意:

即使您知道如何从密钥中检索时间戳,在生产代码中这样做也是一个坏主意。时间戳用于生成唯一的、按时间顺序排列的序列。如果 Firebase 的某个人找到了一种更有效的方法(无论他们碰巧选择了哪种主观的效率定义)来实现相同的目标,他们可能会更改 push 的算法。如果您的代码需要时间戳,则应将时间戳添加到数据中;不依赖于它成为您密钥的一部分。

更新

Firebase 记录了 the algorithm behind Firebase push IDs。但上述建议仍然存在:不要将其用作存储日期的替代方法。

【讨论】:

  • 让我重申这是一个坏主意。使用 Firebase.ServerValue.TIMESTAMP。将时间戳存储在数据中。它是可排序、可查询且可靠的。
  • 我认为它很好地回答了这个问题。我只是不认为这是正确的问题。 (虽然我在一年前问过同样的问题;这实际上是一个副本,但我找不到原件)
  • 因此接受但拒绝投票是正确的做法。除非您找到重复项,在这种情况下,您应该将问题标记为重复项。 :-)
  • 用于生成密钥的算法现在记录在 Firebase 博客中:firebase.com/blog/2015-02-11-firebase-unique-identifiers.html。 Firebases 之间的共识似乎是,他们仍然建议在生产中不要依赖它,而是使用Firebase.ServerValue.TIMESTAMP。事实上,这篇博文重申了这一事实,并解释了为什么这种方法更可取的另一个原因。
  • 如果您需要添加时间戳,这是一个很大的帮助。基于此,您可以为旧值重新创建所有时间戳。所以,我投了赞成票。 :)
【解决方案2】:

这是用 Swift 重写的 Frank's code 版本(撰写本文时为 4.2。)

需要明确的是,我的用例是修补没有时间戳的旧模型(createdAtupdatedAt。)我可以在其中添加随机日期,以免让我头疼。但这与他们的模型无关。根据我从其他文章中读到的内容,我知道这些自动 ID 中包含了时间元素。

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)!
}

在此处获取 Playground 就绪代码:https://gist.github.com/mkval/501c03cbb66cef12728ed1a19f8713f7

【讨论】:

    【解决方案3】:

    在python中

    PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
    
    def get_timestamp_from_id(id):
        timestr = id[0:8]
        timestamp = 0
        for idx, ch in enumerate(timestr):
            timestamp = timestamp * 64 + PUSH_CHARS.index(ch)
        return timestamp/1000
    

    【讨论】:

      猜你喜欢
      • 2023-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 2017-07-02
      相关资源
      最近更新 更多