答案 0 :(得分:32)
正如我在评论中所说,你不应该依赖于从生成的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。但上述建议仍然存在:不要将此作为存储日期的替代方法。
答案 1 :(得分:0)
这是Frank's code的一个版本,已用Swift重新编写(撰写本文时为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)!
}
在https://gist.github.com/mkval/501c03cbb66cef12728ed1a19f8713f7处获取可在操场上使用的代码。
答案 2 :(得分:0)
在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