I have this data structure, where todos are organized to follow path /todos/uid/
{ "metausers" : { "simplelogin:1" : { "displayName" : "John Doe", "provider" : "password", "provider_id" : "1" }, "simplelogin:2" : { "displayName" : "GI Jane", "provider" : "password", "provider_id" : "2" } }, "todos" : { "simplelogin:1" : { "-JUAfv4_-ZUlH7JqM4WZ" : { "completed" : false, "done" : false, "group" : false, "private" : false, "subject" : "First" }, "-JUAfveXP_sqqX32jCJS" : { "completed" : false, "done" : false, "group" : false, "private" : true, "subject" : "Second" }, "-JUAfwXnMo6P53Qz6Fd2" : { "completed" : false, "done" : false, "group" : false, "private" : false, "subject" : "Third" } }, "simplelogin:2" : { "-JUAg9rVemiNQykfvvHs" : { "completed" : false, "done" : false, "group" : false, "private" : false, "subject" : "Q first" }, "-JUAgAmgPwZLPr2iH1Ho" : { "completed" : false, "done" : false, "group" : false, "private" : false, "subject" : "Q second" }, "-JUAgBfF8f7V5R5-XgrY" : { "completed" : false, "done" : false, "group" : false, "private" : true, "subject" : "Q third" } } } }
and i would like to query todos to get all records with private:true
. Is this possible using firebase (angularfire) and how should i do it ? Or should i denormalize a bit more and arrange path /private to avoid of walking down todos ?
We can filter data in one of three ways: by child key, by key, or by value. A query starts with one of these parameters, and then must be combined with one or more of the following parameters: startAt , endAt , limitToFirst , limitToLast , or equalTo .
The limitToLast() method is used to set a maximum number of children to be synced for a given callback. If we set a limit of 100, we will initially only receive up to 100 child_added events. If we have less than 100 messages stored in our database, a child_added event will fire for each message.
Inherited from Query.orderByChild. Generates a new Query object ordered by the specified child key. Queries can only order by one key at a time. Calling orderByChild() multiple times on the same query is an error. Firebase queries allow you to order your data by any child key on the fly.
Firebase data is retrieved by either a one time call to GetValueAsync() or attaching to an event on a FirebaseDatabase reference. The event listener is called once for the initial state of the data and again anytime the data changes.
Assuming you have the uid, this should be straightforward with the following:
var uid = "simplelogin:1"; var todosRef = new Firebase("https://yourdb.firebaseio.com/todos/" + uid); var privateTodosRef = todosRef.orderByChild("private").equalTo(true); var privateTodos; privateTodosRef.on("value", function(response) { privateTodos = response.val(); });
This should return an object with all of this user's private todos, organized by their todo key (ie "-JUAfv4_-ZUlH7JqM4WZ"
. If you'd like to use Angularfire you can wrap this in a $firebaseArray and assign it as follows:
$scope.privateTodos = $firebaseArray(privateTodosRef);
Here's a reference for more info on complex queries, and as mentioned in the other responses there are some nice optimizations that can be done with priorities and restructuring.
Happy coding!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With