web-dev-qa-db-ja.com

FirebaseでPush()を使用する場合、一意のIDを取得する方法

Firebaseデータベースのエントリを追加/削除しようとしています。追加/変更/削除するテーブル(フロントエンド)にリストしたいのですが、変更/削除するために各エントリを一意に識別する方法が必要です。 Firebaseは、Push()を使用するとデフォルトで一意の識別子を追加しますが、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>

次に、3行のデータがあると仮定します。

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"
54
Front_End_Dev

スナップショットの「名前」(この場合、Push()によって作成されたID)を取得するには、次のようにname()を呼び出します。

_var name = snapshot.name();
_

Push()によって自動生成された名前を取得したい場合、次のように返された参照でname()を呼び出すことができます。

_var newRef = myDataRef.Push(...);
var newID = newRef.name();
_

注:snapshot.name()は廃止されました。他の回答をご覧ください。

41
Andrew Lee

この質問を見つけてFirebase 3+、プッシュ後に自動生成されたオブジェクトの一意のIDを取得する方法は、promiseでkeyプロパティ(not method)を使用することです。スナップショット:

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

詳しくは Firebase docs をご覧ください。

サイドノートとして、独自の一意のIDを生成することを検討している人は、それについて二度考えるべきです。セキュリティとパフォーマンスに影響する場合があります。不明な場合は、FirebaseのIDを使用してください。タイムスタンプが含まれており、すぐに使えるセキュリティ機能がいくつかあります。

それについての詳細 ここ

Push()によって生成された一意のキーは現在の時間順に並べられているため、結果のアイテムのリストは時系列でソートされます。キーは推測できないように設計されています(72ビットのエントロピーがランダムに含まれています)。

54
Dan Mindru

snapshot.name()は廃止されました。代わりにkeyを使用してください。 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);
});
33
Rima

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を生成し、このrefの_.key_を使用すると、uniqueIDを取得できます。

6
Denis Markov

@Rimaが指摘したように、key()は、Push()に割り当てられたID firebaseを取得する最も簡単な方法です。

ただし、仲介者を切り捨てたい場合、FirebaseはID生成コードを含むGistをリリースしました。これは単に現在の時間の関数であり、サーバーとの通信なしでも一意性を保証する方法です。

それにより、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;
  };
})();
4
Brandon

_snapshot.key_で.then()の後に.Push()によって返されるプロミスを使用して、ObjectIDを追加してレコードを更新できます。

_const ref = Firebase.database().ref(`/posts`);
ref.Push({ title, categories, content, timestamp})
   .then((snapshot) => {
     ref.child(snapshot.key).update({"id": snapshot.key})
   });
_
2
Lew

私がそれをした方法:

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

これで、さらに使用するためにキーを保持できます。

0
Deepesh

別の呼び出しを行わずにデータベースへの書き込み中または書き込み後にfirebase Push()メソッドによって生成された一意のキーを取得する場合は、次のようにします。

_var reference = firebaseDatabase.ref('your/reference').Push()

var uniqueKey = reference.key

reference.set("helllooooo")
.then(() => {

console.log(uniqueKey)



// this uniqueKey will be the same key that was just add/saved to your database



// can check your local console and your database, you will see the same key in both firebase and your local console


})
.catch(err =>

console.log(err)


});
_

Push()メソッドには、データベースに書き込む前、後、または書き込み中に使用できる、生成されたばかりのキーを提供するkeyプロパティがあります。

0