Skip to content
This repository has been archived by the owner on Aug 25, 2018. It is now read-only.

Error using Firebase Query in Firebase Collection #126

Closed
carnevalle opened this issue Dec 31, 2014 · 9 comments
Closed

Error using Firebase Query in Firebase Collection #126

carnevalle opened this issue Dec 31, 2014 · 9 comments

Comments

@carnevalle
Copy link

I am trying to use a Query on my collection like in this example:

var TodoList = Backbone.Firebase.Collection.extend({
  url: new Firebase('https://<your-firebase>.firebaseio.com/todos').orderByChild('importance')
});

It returns an error because backbonefire.js tries to access .child() in line 753 while creating the Collection:

newItem.firebase = self.firebase.child(newItem.id);

I have only fiddled with firebase and backbonefire for a few hours, so I don't know the API that well, but it seems like the orderByChild returns a Query-object and backbonefire expects a Firebase Reference.

This seems to fix the issue (or at least not make it fail):

newItem.firebase = self.firebase.ref().child(newItem.id);

Am I doing something wrong or is this a bug?

@davideast
Copy link
Contributor

This is a known bug that has been addressed in the 0.5.1 version. I'm waiting for the holiday season to be over before releasing. I plan to have 0.5.1 released by the end of this week.

Your referenced fix is correct. There is another issue (also fixed in 0.5.1) that causes collections to improperly sort. The comparator function is on the prototype of the SyncCollection rather than the Backbone.Firebase.Collection prototype.

If you want to grab the beta release you can check out the 0.5.1 branch. I don't expect many (if any) changes to be made before releasing.

It would be helpful to know if those fixes work for you.

@carnevalle
Copy link
Author

Great! Thank you! (also for responding so fast :-))

@carnevalle
Copy link
Author

I just tried to use 0.5.1 and as you said it fixed the issue with the Query, but the collection is still not rendered in the order requested.

I am ordering by a datestring and Firebase returns as expected.
2014-08-07 20:00:00
2014-08-10 19:00:00
2014-08-17 17:00:00
2014-08-31 17:00:00

It seems like backbonefire is currently sorting the collection by id, which is not what I would expect when ordering by a child.

comparator: function(model) {
      return model.id;
}

Perhaps firebase should respond with a sort-property to make sure the collection maintains the correct sort?

@davideast
Copy link
Contributor

You also need to set the comparator manually. Below I wrote a custom collection factory that provides for easy creation of ordered collections. This code snippet will be added to the README once the 0.5.1 release ships.

I see the issue with having to specify the order in two places. I'll take this into account for future versions, but for now it may be best to provide as much control as possible for sorting on the client.

Let me know if this code (or a similar version that fits your needs) works for you.

 var OrderedCollection = Backbone.Firebase.Collection.extend({
  url: function() {
    return new Firebase('https://<your-firebase>.firebaseio.com/todos').orderByChild(this.criteria);
  }
});

OrderedCollection.create = function(criteria) {
  var CriteriaCollection = OrderedCollection.extend({
    initialize: function(attrs, options) {
      this.criteria = criteria;
    },
    comparator: function(model) {
      return model[criteria];
    }
  });
  return new CriteriaCollection();
};

var collection = OrderedCollection.create('category');

@carnevalle
Copy link
Author

What about changing line 658 to

Backbone.Collection.prototype.add.call(this, [model], {sort: false});

This renders the collection in the order the models were added (returned by Firebase). Then you could trigger a manual sort later if you want to sort the collection otherwise?

Edit:
(Of course this doesn't maintain sort when new items are added. Damnit)

@davideast
Copy link
Contributor

I'll take a deeper look into this issue later on in the week. For now the code snippet I provided above should hold you over. Let me know if you run into any problems with it.

@carnevalle
Copy link
Author

I'll work with the snippet above, but I am using Firebase to build a mobile application, so I am trying to make the client do as little work as possible.

Perhaps it could be an option to disable sort when data is added initially and only sort on updates. Like you are able to disable autosync?

@davideast
Copy link
Contributor

It shouldn't matter that it's on mobile. Backbone itself does the sorting and unless you're sorting hundreds or thousands of objects it should perform fine.

I'll look into customizing the sort option. There may be a way to nix client-side sorting all together and let Firebase keep the array in sync. I believe this is currently what $asArray() in AngularFire does.

@davideast
Copy link
Contributor

See #134.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants