Niles Tanner Niles Tanner - 3 months ago 10
Javascript Question

Obtaining a single item from firebase list

Firebase allows you to query for a single value in a list if you know it's key. However it seems tricky to obtain a single value in a list if you don't have the key.

I've been able to retrieve the desired item, however the solution seems verbose and a bit hacky.

Heres my function:
(fbutil is my firebase url reference base)

function getCopy(number){
var defer = $q.defer();
var ref = fbutil.ref('copies').orderByChild("number").equalTo(number);
ref.once("value",function(copySnap){
if(!copySnap.exists()){
defer.reject(null);
}else{
var listObj = copySnap.val();
var list = Object.keys(listObj).map(function(copy){
return listObj[copy]});
defer.resolve(list[0]);
}
})
return defer.promise;
}


This code does work however I wonder if there is a better way to obtain the item. Is there a firebase function that I am missing? Or a cleaner way to extract the item?

Answer

Your function could be made a little simpler.

With the Firebase 3 API:

The once function returns a promise, so you don't need to create your own. And you could use the snapshot's forEach function to enumerate the children - returning true to short-circuit the enumeration after the first child:

function getCopy (number) {
  var ref = fbutil.ref('copies').orderByChild("number").equalTo(number);
  return ref.once("value").then(function (copiesSnap) {
    var result = null;
    copiesSnap.forEach(function (copySnap) {
      result = copySnap.val();
      return true;
    });
    return result;
  });
}

With the Firebase 2 API:

once does not return a promise, but you could still use the snapshot's forEach function to enumerate the children - returning true to short-circuit the enumeration after the first child:

function getCopy (number) {
  var defer = $q.defer();
  var ref = fbutil.ref('copies').orderByChild("number").equalTo(number);
  ref.once("value", function (copiesSnap) {
    var result = null;
    copiesSnap.forEach(function (copySnap) {
      result = copySnap.val();
      return true;
    });
    defer.resolve(result);
  });
  return defer.promise;
}
Comments