Search code examples
javascriptfirebasefirebase-realtime-databaseunique-index

Firebase Data Collection with Unique Member


I would like to show a list of toys. ach toy as a unique name. The name can contain any character, so it can have a dot a slash or a dollar. This is why I would prefer to use the push method to get a generated key.

The code I end up with is troublesome. It is not thread safe and I could end up with duplicate toys. Is there a better way?

var child = testsRef.orderByChild("name").equalTo("Meccano");

return child.once('value').then(function(snapshot) {
  var snap = snapshot.val();
  if (snapshot.val()) {
    alert('Toy ' + value + ' already exists.');
  } else {
    var newPostKey = testsRef.push().key;
    var updates = {};
    updates[newPostKey] = {          name: value        };
    var result = testsRef.update(updates);
    alert('We can only assume that it has worked.' + result);
  }
});

I built a complete working codepen to illustrate my question here: http://codepen.io/paganaye/pen/EWrayY


Solution

  • Use the toy name as the key but first run it through a firebase key sanitizer like:

    function fbKeySanitizer(str) {
      return encodeURIComponent(str).replace(/[.$[\]#\/]/g, function (c) {
        return '%' + c.charCodeAt(0).toString(16).toUpperCase();
      });
    }
    

    You can either save the original name as a property like you would with the push() method or you can use decodeURIComponent() to reverse the encoding to get back to the exact same string.