How to orderByChild for values with generated keys?

274 views
Skip to first unread message

Gareth Arch

unread,
Mar 13, 2016, 1:01:54 AM3/13/16
to Firebase Google Group
I've been trying to do this for a little while now and have found references from others on trying to do it, but no actual answers that seem to solve the problem.  It seems to be something that others *should* be running into unless I'm doing something wrong in my method for storing the data.

Setup:
I have a data structure of readers, that I have "push"ed onto the readers path - 

readers:
-KCY-TO_cdNKNK4_ctRm
 firstName: "Billy"
 lastName: "Bobber"
 -KCZ0Skmn-k_ur673V-m
 firstName: "Jimmy"
 lastName: "Jones"
 -KCZ1H65vKsdyeNxA2zU
 firstName: "Bo"
 lastName: "Jackson"

At this point, I'm trying to orderByChild "lastName".  The data all comes back sorted lexicographically, which makes sense as nothing under "readers" has a "lastName" child, but everything under the generated key *does*.

So the question is, how do I orderByChild for lastName (or any child) under the generated key?
I was trying to do ref.childByAppendingPath("/readers").queryOrderedByChild("lastName") but that doesn't seem to work (for my reasoning above, I'm guessing)

Any help would be appreciated.
Thanks,

Tom Larkworthy

unread,
Mar 13, 2016, 1:10:21 AM3/13/16
to Firebase Google Group

Order by child is the function you want. Query on the readers path. Readers is equivalent to dinosaur in the dinosaur example here: https://www.firebase.com/docs/web/api/query/orderbychild.html
Try the Dino database out

--
You received this message because you are subscribed to the Google Groups "Firebase Google Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebase-tal...@googlegroups.com.
To post to this group, send email to fireba...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/firebase-talk/12250fe9-50c0-44be-a488-ab3db5233329%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gareth Arch

unread,
Mar 13, 2016, 2:16:26 PM3/13/16
to Firebase Google Group
Yup, that's exactly what I tried, but it did not sort my data by lastName.  I see now what you mean that dinosaurs is equivalent to readers, and each dinosaur name is equivalent to the generated key.  Is there a way to debug this from my side so I can see why it's not working?  Perhaps a way to log each time it tries to sort/order them?

Gareth Arch

unread,
Mar 13, 2016, 2:16:41 PM3/13/16
to Firebase Google Group
Hmm...ok, I tried pointing at the dinosaurs example and then doing the same ordering by height in the example.  I'm using iOS
e.g.
firebaseRef.childByAppendingPath("/readers").queryOrderedByChild("lastName")
but that still just sorts lexicographically.

The dinosaurs example also just sorted lexicographically.


On Sunday, March 13, 2016 at 1:10:21 AM UTC-5, Tom Larkworthy wrote:

Tom Larkworthy

unread,
Mar 13, 2016, 2:32:05 PM3/13/16
to Firebase Google Group

I would expect your readers path to emit child_added events in the order: bobber, jackson, Jones. What order are you getting/expecting?

Gareth Arch

unread,
Mar 13, 2016, 3:12:24 PM3/13/16
to Firebase Google Group
I'm using this via nativescript and am using the npm firebase-plugin-nativescript in order to access the underlying iOS/android SDKs.  I see that I have a "singleEvent:true" and when I use that it returns back the entire datasnapshot, but in "key" order.  When I removed that, I get back individual childAdded events, and they are sorted in the correct order.  
With singleEvent set to true, the iOS that is being called uses:
observeSingleEventOfType::WithBlock:

I guess I'm getting confused on implementation here.   If I don't listen for the childAdded events, then I just get back a datasnapshot of what readers looks like without any kind of sorting.  If I listen for the childAdded events (singleEvent:false), then firebase emits individual events as it sorts the data?  Is this standard practice for how the sorting works and how I should listen/wait for the data to be returned, or should the entire datasnapshot be returned as one block nicely sorted and I'm not doing something correct?

Thanks for the help in understanding this...I'm just getting started with firebase and am trying to get my head around the emitted events, sorting, snapshots, references and all of the rest of the power of the platform :)

Frank van Puffelen

unread,
Mar 13, 2016, 3:17:21 PM3/13/16
to Firebase Google Group
Note that (as Tom says) the use of child_added/.ChildAdded is crucial here. If you listen for a value/.Value event and simply print the resulting Dictionary, the order is undefined (as the order of items in a dictionary is undefined).

Tom Larkworthy

unread,
Mar 13, 2016, 3:28:21 PM3/13/16
to Firebase Google Group

Ahhh cool. I get the issue. So when you do a value event you get the whole reader subtree. It's serialised as JSON object, so there is no ordering, unlike a JSON array. It's a dictionary. It doesn't make sense to order a value event source.

You want child added added events, which return individual elements under the path queried, and then those can be ordered.

So value events are for whole subtrees (including leaf value objects), child added/changed/removed/updated are useful for when you path represents a collection. I am not familiar with the plugin your using but hopefully you can see how that fits in with how your using it.
Child_added will continued to be called every time the list is updated in real-time with the new element in question. A value event would be raised also every update but exposing the whole list each update rather than just the new element added.
Not sure how that gets into the plugin but that's what is happening in the SDK.

Gareth Arch

unread,
Mar 14, 2016, 10:48:31 AM3/14/16
to Firebase Google Group
Yeah, I see digging into the plugin a bit that the observers are added for ChildAdded with observeEventTypeWithBlock and observeSingleEventOfTypeWithBlock for the ValueChanged.  I modified it slightly to use observeEventTypeWithBlock for the ValueChanged and it looks like that just gets fired once initially, and then the ChildAdded gets fired multiple times (as the ordering/sorting is performed), but then ValueChanged is not fired again after the sorting completes?!?  Is that expected?  Is there a way to get the completed sorted data in one go? Or do I still have to manage that from my end listening for the ChildAdded events.  If not then I guess I'll just get the initial snapshot, then sort client side.

Tom Larkworthy

unread,
Mar 14, 2016, 12:59:20 PM3/14/16
to Firebase Google Group
Hi Gareth, there is a section called "Database Event Guarantees": https://www.firebase.com/docs/web/guide/retrieving-data.html

Value events are raised *after* child events, and are guaranteed to contain the newest information. So you should be able to listen to a value event to know when the list has finishes, but use the child_added events to get the elements in the sorted order.  


Kato Richardson

unread,
Mar 14, 2016, 1:15:13 PM3/14/16
to Firebase Google Group

Gareth Arch

unread,
Mar 14, 2016, 11:19:41 PM3/14/16
to Firebase Google Group
Thanks for the assistance with understanding this!  I'll probably use some of these notions to update the plug-in, as right now, based on this discussion, it's not currently working as it should.  Thanks both.
Reply all
Reply to author
Forward
0 new messages