在Firebase中使用push()时如何提取唯一的ID

我正在尝试从Firebase数据库中添加/删除条目。 我想列出他们在表中添加/修改/删除(前端),但我需要一种方法来唯一标识每个条目,以修改/删除。 使用push()时,Firebase默认会添加一个唯一的标识符,但是我没有看到任何引用如何在API文档中select此唯一标识符的内容。 这甚至可以做? 我应该使用set(),所以我正在创build唯一的ID?

我把这个快速的例子放在一起使用他们的教程:

<div id='messagesDiv'></div> <input type='text' class="td-field" id='nameInput' placeholder='Name'> <input type='text' class="td-field" id='messageInput' placeholder='Message'> <input type='text' class="td-field" id='categoryInput' placeholder='Category'> <input type='text' class="td-field" id='enabledInput' placeholder='Enabled'> <input type='text' class="td-field" id='approvedInput' placeholder='Approved'> <input type='Button' class="td-field" id='Submit' Value="Revove" onclick="msgRef.remove()"> <script> var myDataRef = new Firebase('https://unique.firebase.com/'); $('.td-field').keypress(function (e) { if (e.keyCode == 13) { var name = $('#nameInput').val(); var text = $('#messageInput').val(); var category = $('#categoryInput').val(); var enabled = $('#enabledInput').val(); var approved = $('#approvedInput').val(); myDataRef.push({name: name, text: text, category: category, enabled: enabled, approved: approved }); $('#messageInput').val(''); } }); myDataRef.on('child_added', function(snapshot) { var message = snapshot.val(); displayChatMessage(message.name, message.text, message.category, message.enabled, message.approved); }); function displayChatMessage(name, text, category, enabled, approved, ) { $('<div/>').text(text).prepend($('<em/>').text(name+' : '+category +' : '+enabled +' : '+approved+ ' : ' )).appendTo($('#messagesDiv')); $('#messagesDiv')[0].scrollTop = $('#messagesDiv')[0].scrollHeight; }; </script> 

现在让我们假设我有三行数据:

 fred : 1 : 1 : 1 : test message 1 fred : 1 : 1 : 1 : test message 2 fred : 1 : 1 : 1 : test message 3 

我怎么去唯一地识别第2行?

在Firebase数据库中,它们看起来像这样:

 -DatabaseName -IuxeSuSiNy6xiahCXa0 approved: "1" category: "1" enabled: "1" name: "Fred" text: "test message 1" -IuxeTjwWOhV0lyEP5hf approved: "1" category: "1" enabled: "1" name: "Fred" text: "test message 2" -IuxeUWgBMTH4Xk9QADM approved: "1" category: "1" enabled: "1" name: "Fred" text: "test message 3" 

要获得任何快照的“名称”(在这种情况下,由push()创build的ID只需调用name()就可以了:

 var name = snapshot.name(); 

如果你想得到由push()自动生成的名字,你可以在返回的引用上调用name(),如下所示:

 var newRef = myDataRef.push(...); var newID = newRef.name(); 

注意: snapshot.name()已被弃用。 查看其他答案。

snapshot.name()已被弃用。 使用key代替。 任何DataSnapshot上的key属性(除了表示Firebase根目录的key属性)都将返回生成该关键字的位置的关键名称。 在你的例子中:

 myDataRef.on('child_added', function(snapshot) { var message = snapshot.val(); var id = snapshot.key; displayChatMessage(message.name, message.text, message.category, message.enabled, message.approved); }); 

对于任何人发现这个问题,并使用Firebase 3+ ,推后的方式是获得自动生成对象唯一标识是通过使用承诺快照的key属性( 而不是方法 ):

 firebase .ref('item') .push({...}) .then((snap) => { const key = snap.key }) 

详细了解Firebase文档 。

作为一个侧面说明,那些考虑产生自己的唯一ID的人应该三思而后行。 它可能有安全和性能的影响。 如果您不确定,请使用Firebase的ID。 它包含一个时间戳,并具有一些整洁的安全function。

更多关于这里 :

由push()生成的唯一键按当前时间sorting,因此结果列表将按时间顺序sorting。 密钥也被devise成不可猜测的(它们包含72个随机的熵位)。

正如@Rima指出的, key()是获取ID分配给你的push()的最直接的方法。

但是,如果你想切断中间人,Firebase发布了一个ID代码的要点。 这只是当前时间的一个function,这是他们如何保证唯一性,即使不与服务器通信。

有了这个,你可以使用generateId(obj)set(obj)来复制push()的function。

这是IDfunction :

 /** * Fancy ID generator that creates 20-character string identifiers with the following properties: * * 1. They're based on timestamp so that they sort *after* any existing ids. * 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs. * 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly). * 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the * latter ones will sort after the former ones. We do this by using the previous random bits * but "incrementing" them by 1 (only in the case of a timestamp collision). */ generatePushID = (function() { // Modeled after base64 web-safe chars, but ordered by ASCII. var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; // Timestamp of last push, used to prevent local collisions if you push twice in one ms. var lastPushTime = 0; // We generate 72-bits of randomness which get turned into 12 characters and appended to the // timestamp to prevent collisions with other clients. We store the last characters we // generated because in the event of a collision, we'll use those same characters except // "incremented" by one. var lastRandChars = []; return function() { var now = new Date().getTime(); var duplicateTime = (now === lastPushTime); lastPushTime = now; var timeStampChars = new Array(8); for (var i = 7; i >= 0; i--) { timeStampChars[i] = PUSH_CHARS.charAt(now % 64); // NOTE: Can't use << here because javascript will convert to int and lose the upper bits. now = Math.floor(now / 64); } if (now !== 0) throw new Error('We should have converted the entire timestamp.'); var id = timeStampChars.join(''); if (!duplicateTime) { for (i = 0; i < 12; i++) { lastRandChars[i] = Math.floor(Math.random() * 64); } } else { // If the timestamp hasn't changed since last push, use the same random number, except incremented by 1. for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) { lastRandChars[i] = 0; } lastRandChars[i]++; } for (i = 0; i < 12; i++) { id += PUSH_CHARS.charAt(lastRandChars[i]); } if(id.length != 20) throw new Error('Length should be 20.'); return id; }; })(); 

我是如何做到这一点的:

 FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance(); DatabaseReference ref = mFirebaseDatabase.getReference().child("users").child(uid); String key = ref.push().getKey(); // this will fetch unique key in advance ref.child(key).setValue(classObject); 

现在你可以保留密钥以备后用。

push()之后得到uniqueID ,你必须使用这个变体:

 // Generate a reference to a new location and add some data using push() var newPostRef = postsRef.push(); // Get the unique key generated by push() var postId = newPostRef.key; 

当你push()和使用这个ref的.key ,你可以生成一个新的Ref ,你可以得到uniqueID