Firebase: 如何为关键字生成唯一数字ID?

71

我需要用数字ID方便人们阅读。在Firebase中如何获得?

我想要用数字ID作为键,例如“000000001”,“000000002”,“00000003”,“00000004”。

我需要这样的ID作为永久对象ID,无论在线还是离线。我希望用户只需输入URL“/objects/00000001”就能浏览该对象页面,而不需要额外的努力。

我在这里提问,是因为我想知道是否可以不使用“ .priority ”,子属性等方法来实现。我猜“ set ”方法可以以某种方式实现。如果不可能,请告诉我不行,我可以接受这个答案。


请查看http://stackoverflow.com/help/how-to-ask。您尝试过任何解决方案吗?您是否已经阅读了Firebase文档? - sbolel
5个回答

81
我建议阅读Firebase文档。具体来说,请参阅Firebase JavaScript Web Guide中的Saving Data部分。
从指南中可以得到以下信息:
获取push()生成的唯一ID
调用push()将返回对新数据路径的引用,您可以使用它来获取其ID的值或将数据设置为它。以下代码将导致与上面的示例相同的数据,但现在我们将访问生成的唯一push ID。
// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push({
 author: "gracehop",
 title: "Announcing COBOL, a New Programming Language"
});

// Get the unique ID generated by push() by accessing its key
var postID = newPostRef.key;

来源: https://firebase.google.com/docs/database/admin/save-data#section-ways-to-save

  • 推送操作会生成一个新的数据路径,其key为服务器时间戳。这些键看起来像-JiGh_31GA20JabpZBfa,因此不是数字。
  • 如果您想要创建仅包含数字的ID,则可以将其作为对象的参数,以避免覆盖生成的键。
    • 这些键(新数据的路径)保证是唯一的,因此没有必要用数字键覆盖它们。
    • 相反,您可以将数字ID设置为对象的子项。
    • 然后,您可以使用Firebase Queries按该ID子项查询对象。

来自指南:

在JavaScript中,调用push()然后立即调用set()的模式非常常见,我们允许您将它们合并,只需直接将要设置的数据传递给push()即可。以下两个写操作都将导致相同的数据保存到Firebase:
// These two methods are equivalent:
postsRef.push().set({
  author: "gracehop",
  title: "Announcing COBOL, a New Programming Language"
});
postsRef.push({
  author: "gracehop",
  title: "Announcing COBOL, a New Programming Language"
});

来源: https://firebase.google.com/docs/database/admin/save-data#getting-the-unique-key-generated-by-push

这个链接是关于Firebase数据库的内容,介绍了如何通过push()方法生成唯一键。

9
似乎newPostRef.key()不再起作用了... newPostRef.key确实返回生成的键。它似乎直接与属性相关联,而不是从名为key()的函数中返回。 - Adam
1
有关此事有任何更新吗?我尝试了提到的方法,但它们都不起作用。链接不再有效。 此外,当前的Firebase指南无法从推送中获取ID。 我只得到了Uncaught SyntaxError:Unexpected identifier。 - Viet
@SinanBolel 如果我想将该键用作子ID,那么我应该在获取引用后再次推送它吗? - Murhaf Sousli
我猜push是经过服务器的,然后再返回?我想要立即获取唯一ID。我可以自己制作一个,但只是想知道FB是否在客户端库中有内置功能。 - Dominic
有人能给一个 postsRef 的例子吗?它可以是一个集合的引用吗? - Cyberguy Game
显示剩余3条评论

14
如上所述,您可以使用Firebase默认的推送ID。
如果您想要数字内容,可以基于时间戳来避免冲突。
例如,可以使用日期、小时、秒、毫秒和一些随机整数来生成ID。
01612061353136799031

这翻译成:

016-12-06 13:53:13:679 9031

这完全取决于您所需的精度(社保号码也是如此,日期后面加上一些随机字符)。例如,一天、一小时或一秒钟内预计有多少交易。您可能希望降低精度以方便输入。
您还可以执行一个递增编号的交易,在成功后,您将为该用户获得唯一的连续编号。这些可以在客户端或服务器端完成。

(https://firebase.google.com/docs/database/android/read-and-write)


4
这并不是一种安全的方法,因为只需循环尝试所有可能的值就可以产生冲突。使用push方法生成的哈希值可能更好,虽然我不知道使用了什么算法。 - T9b
@T9b,没有循环遍历所有可能的值,因为日期总是递增的。推送算法基本上也是如此。 - htafoya
没错,就是这样做。日期、时间和随机数都是完全递增的,这正是为什么它不安全的原因。就像我说的那样,你可以通过逐个递增过去所有可能的日期和时间来破解它。 - T9b
6
秘密ID并不是必须的,以Facebook为例,您可以简单地开始输入整数来获取用户配置文件(MZ为4)。但您实际上无法使用该数据做更多事情。 - htafoya

3

补充 @htafoya的回答。 代码片段如下:

const getTimeEpoch = () => {
    return new Date().getTime().toString();                             
}

1

文档所述,这可以通过使用set而不是push来实现。

正如文档所述,不建议这样做(由于可能会被其他用户在“相同”的时间覆盖)。

但在某些情况下,控制源的内容(包括键)是有帮助的。

作为js中webapp的示例,193是您在其他地方生成的id,只需:

 firebase.initializeApp(firebaseConfig);
  var data={
      "name":"Prague"
  };
  firebase.database().ref().child('areas').child("193").set(data);

这将覆盖任何标记为193的区域,如果不存在,则创建一个。

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接