根据这篇博文,firebase 数组键是使用时间戳创建的:
它通过根据当前时间戳(与服务器时间匹配的偏移量)分配一个永久的、唯一的 id 来做到这一点。
有没有办法恢复这个时间戳供以后使用,给定密钥?
根据这篇博文,firebase 数组键是使用时间戳创建的:
它通过根据当前时间戳(与服务器时间匹配的偏移量)分配一个永久的、唯一的 id 来做到这一点。
有没有办法恢复这个时间戳供以后使用,给定密钥?
正如我在评论中所说,您不应依赖从生成的 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 记录了 Firebase 推送 ID 背后的算法。但上述建议仍然存在:不要将其用作存储日期的替代方法。
这是用 Swift 重写的Frank 代码的一个版本(在撰写本文时为 4.2。)
需要明确的是,我的用例是修补没有时间戳(createdAt
,updatedAt
。)的旧模型,我可以在其中添加随机日期,以免让我头疼。但这与他们的模型无关。根据我从其他文章中读到的内容,我知道这些自动 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 。
在蟒蛇中
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