0

My Firebase data is organized this way:

+ myappname
  + customers
    + -JV2NQv3GmoM81zdUfTe
      + name: "Mary"
      + age: "24"
      + ...
    + -JV2N9NnItCfz5vB04RS
      + name: "John"
      + age: "32"
      + ...
    + ...
  + ...

How do I retrieve a customer by it's name?
The name is guaranteed to be unique.
This is my Customer service, currently:

app.factory('Customer', function ($firebase, FIREBASE_URL) {
  var ref = new Firebase(FIREBASE_URL + 'customers');
  var customers = $firebase(ref);

  var Customer = {
    all: customers,
    create: function (customer) {
      return customers.$add(customer).then(function (ref) {
        var customerId = ref.name();
        return customerId;
      });
    },
    set: function(customerId, customer) {
      return customers.$child(customerId).$set(customer);
    },
    find: function (customerId) {
      return customers.$child(customerId);
    },
    findByName: function (customerName) { // TODO...
    },
    delete: function (customerId) {
      var customer = Customer.find(customerId);
      customer.deleted = true;
      customer.$on('loaded', function () {
        customers.$child(customerId).$set(customer);
      });
    }
  };
  return Customer;
});

Should I scan all the customers on each findByName() call?
Or should I build something like a "secondary index"?
Please, some advice, I'm just starting... :-(

MarcoS
  • 17,323
  • 24
  • 96
  • 174
  • 2
    possible duplicate of [Get users by name property using Firebase](http://stackoverflow.com/questions/14963776/get-users-by-name-property-using-firebase) – Kato Aug 24 '14 at 19:30
  • 1
    Even though you're just starting, you've already named two of the possible solutions. Firebase allows you to search nodes by either the name of the node or its priority. If you are not using the priority for anything else yet, you could set the name as the priority and use a `Query.startAt` and `Query.endAt` to select by name. If you're already using priority for something else, you may indeed create a separate index, just for mapping user names to the node names. – Frank van Puffelen Aug 24 '14 at 19:30
  • @Kato: you are right, my question is almost exact duplicate of other one... Sorry I didn't find it before asking... – MarcoS Aug 25 '14 at 07:43

1 Answers1

2

Thanks to Kato indication, and Frank van Puffelen suggestions, I did at last solve my own problem.
I did add an "index", "customersByName", to my Firebase (remembering "Disk space is cheap, user's time is not" Firebase motto... :-).
I did not follow the direction in the referred answer, because I think this solution is of more general use: it scales for multiple "indexes"...
I want to post it here, hoping it can be of any use to other people.
I would like to see comments: does this solution have possible drawbacks? Is it an advisable solution, overall, for some use case?

app.factory('Customer', function ($firebase, FIREBASE_URL) {
  var ref = new Firebase(FIREBASE_URL + 'customers');
  var customers = $firebase(ref);
  var refByName = new Firebase(FIREBASE_URL + 'customersByName');
  var customersByName = $firebase(refByName);

  var Customer = {
    all: customers,
    create: function (customer) {
      return customers.$add(customer).then(function (ref) {
        var customerId = ref.name();
        customersByName.$child(customer.name).$set(customerId);
        return customerId;
      });
    },
    set: function(customerId, customer) {
      var oldname = customers.$child(customerId).name;
      if (customer.name !== oldname) {
        customersByName.$remove(oldname);
      }
      customersByName.$child(customer.name).$set(customerId);
      return customers.$child(customerId).$set(customer);
    },
    find: function (customerId) {
      return customers.$child(customerId);
    },
    findByName: function (customerName) {
      return customersByName.$child(customerName);
    },
    delete: function (customerId) {
      var customer = Customer.find(customerId);
      customer.deleted = true;
      customer.$on('loaded', function () {
        customersByName.$remove(customer.name);
        customers.$child(customerId).$set(customer);
      });
    }
  };

  return Customer;
});
MarcoS
  • 17,323
  • 24
  • 96
  • 174