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

时间:2022-11-25 12:30:38

I'm attempting to add/remove entries from a Firebase database. I want to list them in a table to be added/modified/removed (front end) but I need a way to uniquely identify each entry in order to modify/remove. Firebase adds a unique identifier by default when using push(), but I didn't see anything referencing how to select this unique identifier in the API documentation. Can this even be done? Should I be using set() instead so I'm creating the unique ID?

我正在尝试从一个Firebase数据库中添加/删除条目。我想在要添加/修改/删除的表(前端)中列出它们,但是我需要一种惟一地标识每个条目的方法来修改/删除。在使用push()时,默认情况下,Firebase添加了一个唯一标识符,但我在API文档中没有看到任何引用如何选择这个唯一标识符的内容。这能做到吗?我应该使用set()来创建唯一ID吗?

I've put this quick example together using their tutorial:

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

<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>

Now lets assume I have three rows of data:

现在假设我有三行数据:

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

How do I go about uniquely identifying row 2?

我该如何唯一地识别第2行呢?

in the Firebase Database they look like this:

在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"

6 个解决方案

#1


39  

To get the "name" of any snapshot (in this case, the ID created by push()) just call name() like this:

要获取任何快照的“名称”(在本例中,是push()创建的ID),只需调用name(),如下所示:

var name = snapshot.name();

If you want to get the name that has been auto-generated by push(), you can just call name() on the returned reference, like so:

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

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

NOTE: snapshot.name() has been deprecated. See other answers.

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

#2


36  

To anybody finding this question & using Firebase 3+, the way you get auto generated object unique ids after push is by using the key property (not method) on the promise snapshot:

对于任何发现这个问题的人&使用Firebase 3+,在push之后获得自动生成的对象唯一id的方法是使用承诺快照上的key属性(而不是方法):

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

Read more about it in the Firebase docs.

在Firebase文档中了解更多。

As a side note, those that consider generating their own unique ID should think twice about it. It may have security and performance implications. If you're not sure about it, use Firebase's ID. It contains a timestamp and has some neat security features out of the box.

作为补充说明,那些考虑生成自己唯一ID的人应该三思。它可能具有安全性和性能影响。如果你不确定,可以使用Firebase的ID,它包含一个时间戳,并且有一些现成的安全特性。

More about it here:

更多关于这里:

The unique key generated by push() are ordered by the current time, so the resulting list of items will be chronologically sorted. The keys are also designed to be unguessable (they contain 72 random bits of entropy).

push()生成的惟一键按当前时间排序,因此结果项列表将按时间顺序排序。这些键也被设计成不可猜测的(它们包含72个随机的熵位)。

#3


32  

snapshot.name() has been deprecated. use key instead. The key property on any DataSnapshot (except for one which represents the root of a Firebase) will return the key name of the location that generated it. In your example:

snapshot.name()方法现在已被淘汰。使用的关键。任何DataSnapshot上的key属性(除了一个表示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);
});

#4


3  

As @Rima pointed out, key() is the most straightforward way of getting the ID firebase assigned to your push().

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

If, however, you wish to cut-out the middle-man, Firebase released a gist with their ID generation code. It's simply a function of the current time, which is how they guarantee uniqueness, even w/o communicating w/ the server.

但是,如果您希望删除中间人,Firebase发布了带有其ID生成代码的主旨。它只是当前时间的函数,这是它们保证惟一性的方式,甚至是与w/服务器通信的w/o。

With that, you can use generateId(obj) and set(obj) to replicate the functionality of push()

这样,您就可以使用generateId(obj)和set(obj)来复制push()的功能

Here's the ID function:

这是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;
  };
})();

#5


1  

To get uniqueID after push() you must use this variant:

要在push()之后获得unique eid,您必须使用这个变体:

// 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;

You generate a new Ref when you push() and using .key of this ref you can get uniqueID.

当您push()并使用这个Ref的.key时,您将生成一个新的Ref,您可以获得uniqueID。

#6


0  

How i did it like:

我是怎么做的:

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);

Now you can retain key for further use..

现在你可以留着钥匙继续用了。

#1


39  

To get the "name" of any snapshot (in this case, the ID created by push()) just call name() like this:

要获取任何快照的“名称”(在本例中,是push()创建的ID),只需调用name(),如下所示:

var name = snapshot.name();

If you want to get the name that has been auto-generated by push(), you can just call name() on the returned reference, like so:

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

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

NOTE: snapshot.name() has been deprecated. See other answers.

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

#2


36  

To anybody finding this question & using Firebase 3+, the way you get auto generated object unique ids after push is by using the key property (not method) on the promise snapshot:

对于任何发现这个问题的人&使用Firebase 3+,在push之后获得自动生成的对象唯一id的方法是使用承诺快照上的key属性(而不是方法):

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

Read more about it in the Firebase docs.

在Firebase文档中了解更多。

As a side note, those that consider generating their own unique ID should think twice about it. It may have security and performance implications. If you're not sure about it, use Firebase's ID. It contains a timestamp and has some neat security features out of the box.

作为补充说明,那些考虑生成自己唯一ID的人应该三思。它可能具有安全性和性能影响。如果你不确定,可以使用Firebase的ID,它包含一个时间戳,并且有一些现成的安全特性。

More about it here:

更多关于这里:

The unique key generated by push() are ordered by the current time, so the resulting list of items will be chronologically sorted. The keys are also designed to be unguessable (they contain 72 random bits of entropy).

push()生成的惟一键按当前时间排序,因此结果项列表将按时间顺序排序。这些键也被设计成不可猜测的(它们包含72个随机的熵位)。

#3


32  

snapshot.name() has been deprecated. use key instead. The key property on any DataSnapshot (except for one which represents the root of a Firebase) will return the key name of the location that generated it. In your example:

snapshot.name()方法现在已被淘汰。使用的关键。任何DataSnapshot上的key属性(除了一个表示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);
});

#4


3  

As @Rima pointed out, key() is the most straightforward way of getting the ID firebase assigned to your push().

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

If, however, you wish to cut-out the middle-man, Firebase released a gist with their ID generation code. It's simply a function of the current time, which is how they guarantee uniqueness, even w/o communicating w/ the server.

但是,如果您希望删除中间人,Firebase发布了带有其ID生成代码的主旨。它只是当前时间的函数,这是它们保证惟一性的方式,甚至是与w/服务器通信的w/o。

With that, you can use generateId(obj) and set(obj) to replicate the functionality of push()

这样,您就可以使用generateId(obj)和set(obj)来复制push()的功能

Here's the ID function:

这是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;
  };
})();

#5


1  

To get uniqueID after push() you must use this variant:

要在push()之后获得unique eid,您必须使用这个变体:

// 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;

You generate a new Ref when you push() and using .key of this ref you can get uniqueID.

当您push()并使用这个Ref的.key时,您将生成一个新的Ref,您可以获得uniqueID。

#6


0  

How i did it like:

我是怎么做的:

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);

Now you can retain key for further use..

现在你可以留着钥匙继续用了。