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

Fro*_*Dev 55 javascript jquery firebase

我正在尝试添加/删除Firebase数据库中的条目.我想将它们列在要添加/修改/删除的表中(前端),但我需要一种方法来唯一标识每个条目以便修改/删除.使用push()时,Firebase默认添加唯一标识符,但我没有看到任何引用如何在API文档中选择此唯一标识符的内容.甚至可以这样做吗?我应该使用set()代替所以我正在创建唯一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>
Run Code Online (Sandbox Code Playgroud)

现在假设我有三行数据:

fred : 1 : 1 : 1 : test message 1
fred : 1 : 1 : 1 : test message 2
fred : 1 : 1 : 1 : test message 3
Run Code Online (Sandbox Code Playgroud)

如何唯一识别第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"
Run Code Online (Sandbox Code Playgroud)

Dan*_*dru 55

对于任何发现此问题和使用的人Firebase 3+,在推送后获取自动生成的对象唯一ID的方法是使用promise快照上的key属性(而不是方法):

firebase
  .ref('item')
  .push({...})
  .then((snap) => {
     const key = snap.key 
  })
Run Code Online (Sandbox Code Playgroud)

Firebase文档中了解有关它的更多信息.

作为旁注,那些考虑生成自己的唯一ID的人应该三思而后行.它可能具有安全性和性能影响.如果您不确定,请使用Firebase的ID.它包含一个时间戳,并具有一些开箱即用的整洁安全功能.

更多关于它在这里:

push()生成的唯一键按当前时间排序,因此生成的项列表将按时间顺序排序.密钥也被设计为不可思议的(它们包含72个随机的熵).

  • 这是有效的,接受的答案必须替换为这个 (2认同)

And*_*Lee 41

要获取任何快照的"名称"(在这种情况下,由push()创建的ID)只需调用name(),如下所示:

var name = snapshot.name();
Run Code Online (Sandbox Code Playgroud)

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

var newRef = myDataRef.push(...);
var newID = newRef.name();
Run Code Online (Sandbox Code Playgroud)

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


Rim*_*ima 33

snapshot.name()已被弃用.使用key来代替.key任何DataSnapshot上的属性(代表Firebase根目录的属性除外)都将返回生成它的位置的密钥名称.在你的例子中:

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);
});
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`key`现在是属性,而不是DataSnapshot上的方法:https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#key (5认同)

小智 7

为了得到uniqueIDpush(),你必须使用此变种:

// 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;
Run Code Online (Sandbox Code Playgroud)

Ref当你push()使用.key这个参考时你可以得到一个新的uniqueID.


Bra*_*don 5

正如@Rima 指出的那样,key()是获取分配给您的push().

但是,如果您希望去掉中间人,Firebase 发布了带有 ID 生成代码的要点。它只是当前时间的函数,这就是它们如何保证唯一性,即使没有与服务器通信。

有了它,您可以使用generateId(obj)set(obj)复制push()

这是 ID 函数

/**
 * 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;
  };
})();
Run Code Online (Sandbox Code Playgroud)