Reverse orderByChild, store negative timestamp?

2,307 views
Skip to first unread message

David Notik

unread,
Apr 20, 2015, 6:13:09 PM4/20/15
to fireba...@googlegroups.com
I have orderByChild('createdDate') where createdDate is a millisecondsSinceEpoch timestamp.

The oldest users are coming out on top as expected.

But I'd like to sort newest on top. Does that mean I have to save a negative millisecondsSinceEpoch to a separate field? If so, may as well just use priorities, as they come w/ the added benefit that it won't show/pollute in Forge or in the JSON I receive. But is using priorities discouraged w/ the newer stuff?

Guidance appreciated. Thank you!

David Notik

unread,
Apr 20, 2015, 6:23:47 PM4/20/15
to fireba...@googlegroups.com
I should note, the solution in this related post (to reverse the received results) doesn't apply to me:


That's because I'm not doing a .once('value') but a onChildAdded. In fact, multiple onChildAdded listeners as I infinite scroll down the page. It's all based on a query like:

var queryRef = f.child('/users3')
 
.orderByChild('createdDate')
 
.startAt(priority: lastPriority)
 
.limitToFirst(pageSize + 1);

Frank van Puffelen

unread,
Apr 20, 2015, 8:31:29 PM4/20/15
to fireba...@googlegroups.com
Hi David,

With child_added you get passed two events to the callback:
  1. the DataSnapshot passed into the callback will reflect the data for the relevant child. 
  2. For ordering purposes, it is passed a second argument which is a string containing the name of the previous sibling child
With this information you can keep the local items in (reverse) order, even when using child_added (and the other child_ events) instead of value. You just have to use limitToLast and mentally relabel previousChild to nextChild.

But there is also nothing wrong with adding an extra property for the reversed order. It's probably the quicker of the two solutions to implement.

       Frank

Michael Lehenbauer

unread,
Apr 21, 2015, 11:26:43 AM4/21/15
to fireba...@googlegroups.com
Frank is right on.  Additionally:
  1. Our leaderboard example (https://github.com/firebase/examples/blob/master/leaderboard/) uses this technique to show scores in descending order.  Might be useful.
  2. We are starting to discourage the use of priorities, and new features in the future might not work with priorities.  So I'd use a regular field if you end up going that route.
  3. This is a very reasonable request and we're looking at adding a way to "flip" the ordering client-side in the future to make it easier to render the results in the order of your choosing.
-Michael

--
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/ba14f24d-8237-4e57-b944-218e0ecd22b0%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

David Notik

unread,
Apr 21, 2015, 11:44:20 AM4/21/15
to fireba...@googlegroups.com
Thank you both. It's good to have full confirmation of priorities going away – I recall Jacob had mentioned this months ago too.

I may just use the "second field" approach, but I also want to fully understand the limitToLast approach.


It seems if I limitToLast(20) I'll get the very last 20 of whatever list as determined by orderBy_. If there are null values, those would be last in this case.

But do I also need endAt? I can't quite get this to work beyond the first page:

var queryRef = f.child('/users')

 
.orderByChild('createdDate')
 
.startAt(priority: lastPriority)

 
.limitToLast(pageSize + 1);
...

queryRef.onChildAdded.listen((e) {
 
var user = e.snapshot.val();
 lastPriority 
= user['createdDate'];
...

David Notik

unread,
Apr 21, 2015, 11:54:36 AM4/21/15
to fireba...@googlegroups.com
And re: the "second field" approach, I called it "_priority" – any objections? :)

Michael Lehenbauer

unread,
Apr 21, 2015, 12:13:17 PM4/21/15
to fireba...@googlegroups.com
Yeah, you'll need to use endAt as well.  Basically you'll use limitToLast/endAt instead of limitToFirst/startAt.  And instead of "lastPriority", you probably want "firstPriority."  Basically everything flips. :-)

Regarding null values, null values actually come first, before all non-null values.  So they'd probably show up in limitToFirst(10) rather than limitToLast(10).

-Michael

Reply all
Reply to author
Forward
0 new messages