Skip to content

orderByChild not working #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tegument opened this issue Oct 22, 2016 · 31 comments
Closed

orderByChild not working #82

tegument opened this issue Oct 22, 2016 · 31 comments

Comments

@tegument
Copy link

tegument commented Oct 22, 2016

I have items stored in firebase with a 'createdAt' property which is the server TIMESTAMP. The TIMESTAMP value is being set correctly, but when querying using orderByChild('createdAt') the order is not correct.

I have verified that the same query run with the firebase javascript API works as expected:

firestack.database.ref('images').orderByChild('createdAt').once('value', (snapshot)=>{ // snapshot not ordered by correctly });

Firebase javascript API:

firebaseApp.database().ref('images').orderByChild('createdAt').once('value', (snapshot)=>{ // snapshot ordered correctly });

I have an index set in my firebase rules but can't seem to get Firestack to use the orderByChild query

@tegument
Copy link
Author

If I use the following query the result is in the correct order:

fsImageRef.orderByChild('createdAt').on("child_added", function(snapshot) { console.log(snapshot.val().createdAt); });

Am I not using the correct method? I just need to load all by createdAt

@auser
Copy link
Contributor

auser commented Oct 23, 2016

What platform are you testing it on or is it both (iOS/Android)?

@tegument
Copy link
Author

tegument commented Oct 23, 2016

I'm only testing on android at the moment.

I'm also having the same issue with the following query:

Works with Firebase JS API:
imagePageRef = firebaseApp.database().ref('feeds/'+uid).orderByChild('createdAt').endAt(lastItemKey).limitToLast(pageCount + 1);

Doesn't work with Firestack:
imagePageRef = firestack.database.ref('feeds/'+uid).orderByChild('createdAt').endAt(lastItemKey).limitToLast(pageCount + 1);

Firestack doesn't return correct order and when calling again to get next 'page' of posts based on the last item key endAt it ignores this and returns that last items.

@auser
Copy link
Contributor

auser commented Oct 23, 2016

Great. I'll take a look... thanks for reporting!

Does it work on iOS as expected?

@tegument
Copy link
Author

Np! I'd love to help troubleshoot this further and looked through the JS/Java to see if I could find anything. Please let me know what you find so I can possibly be a better help in the future haha

@tegument
Copy link
Author

I haven't been testing on iOS yet, but if I do i'll let you know.

@auser
Copy link
Contributor

auser commented Oct 25, 2016

I found it, I think. I haven't been able to test it yet, but I'm pretty certain I know the issue

@tegument
Copy link
Author

Awesome! let me know if you have a patch and I can test it out

@auser
Copy link
Contributor

auser commented Oct 26, 2016

@tegument I just pushed a branch called feature/query. Can you try it out there?

@tegument
Copy link
Author

i'm using the following query:

imagePageRef = firestack.database.ref(dbPath).orderByChild('createdAt').endAt(lastItemKey).limitToLast(itemsPerPage + 1);

but receive the following error:

"You can't combine multiple orderBy calls!"

capture

@auser
Copy link
Contributor

auser commented Oct 31, 2016

Yes. I know the fix for this. Apologies about the delay. I've been jet lagged from my trip!

@bitcoinvsalts
Copy link
Contributor

It does not work with iOs either

@chaitanya-bhagavan
Copy link
Contributor

chaitanya-bhagavan commented Nov 12, 2016

@auser I too encountered this issue and after debugging I found that the orderByChild is passed to firebase and the response is indeed sorted on the key specified. The order is getting lost in FirestackUtils.castSnapshotValue. Seems like WritableMap does not maintain the order of insertion.

@auser
Copy link
Contributor

auser commented Nov 13, 2016

Oh yes. I added a map and for each function on snapshot to retain the order

@chaitanya-bhagavan
Copy link
Contributor

@auser I am not sure I understand what you mean.

@chaitanya-bhagavan
Copy link
Contributor

@auser I got what you were saying. But the problem is not in the iteration, it's in WritableMap. When new key/values are pushed it does not maintain the insert order. The solution I can think of is to use a JSON Writer to construct the response.

@auser
Copy link
Contributor

auser commented Nov 13, 2016

It's not about iterating. The way forEach and map work is by using the ordered keys in response. The response, if contains keys returns with objects with keys, the native side returns the list of keys as an ordered array. 
In JS, we have those iterables to handle the looping in order. Feel free to check the implementation for more details. 

On Sun, Nov 13, 2016 at 5:30 AM -0800, "Chaitanya Bhagvan" notifications@github.com wrote:

@auser I got what you were saying. But the problem is not in the iteration, it's in WritableMap. When new key/values are pushed it does not maintain the insert order. The solution I can think of is to use a JSON Writer to construct the response.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@auser
Copy link
Contributor

auser commented Nov 13, 2016

By the way, this is the same approach as the web library takes to handle ordering.

@auser auser closed this as completed Nov 13, 2016
@chaitanya-bhagavan
Copy link
Contributor

@auser If I understand correctly then you are saying the response is an ordered array, but the snapshot.value or snapshot.val() is an object and does not have map or forEach methods on it.

@chaitanya-bhagavan
Copy link
Contributor

@auser This happening only on android. iOS works just fine.

@auser
Copy link
Contributor

auser commented Nov 14, 2016

Not sure how it could... also I was talking about the master branch, not npm. Js objects do not respect ordering on keys, so if it is working, it by happenstance.

@auser
Copy link
Contributor

auser commented Nov 14, 2016

Technically how we handle it is through storing the ordered list of keys and mapping through the array of keys in the forEach and map methods on the snapshot

@smkhalsa
Copy link

smkhalsa commented Dec 1, 2016

@auser I'm having this issue on iOS.

I believe there is an issue with how data is being returned to JS in general, not just with the orderByChild method. In my firebase, I have some data with alphabetic keys such as the following:

  • aa
  • bb
  • cc

In the data browser, it is ordered as above. If I request it with the web JS library, it comes back correctly in the above order. However, when I request this data via firestack, this order is not maintained. Even if I use the orderByKey method, the data still comes back shuffled.

My first thought is that the shuffling might be happening when the data gets transferred from native to JS.

@smkhalsa
Copy link

smkhalsa commented Dec 1, 2016

I should note that I'm using the npm version, not the latest from master

@florianbepunkt
Copy link

florianbepunkt commented Dec 1, 2016

I experience the same issue on V3 branch. orderByChild takes no effect… also using orderByChild and .endAt() has no effect at all. I have a list of messages with a timestamp, trying to query for messages before a given point at time. works with js sdk, but not with firestack (v3 branch)

@chaitanya-bhagavan
Copy link
Contributor

@smkhalsa @florianbepunkt Use the master branch. The one on npm does not have this feature.

@florianbepunkt
Copy link

@chaitanya0bhagvan I created a new issue since I'm using v3 branch… maybe orderByChild is not implemented in this branch yet. #174

@auser
Copy link
Contributor

auser commented Dec 1, 2016

Not sure about the branch (yet), but I just pushed a new npm version (2.3.4), which includes this feature. Notice that the order is maintained by the JS client through a map and forEach function as JS objects do not respect order. In order to keep order, you have to use the JS function.

@florianbepunkt
Copy link

florianbepunkt commented Dec 1, 2016

@auser Thank you. I will wait and see if this is in Michael's branch which I'm using due to the different syntax. If not I will switch and rewrite my firestack calls.

You say we have to use the JS function to keep the order. Is there any extra method involved or can we use something like

firestack
.ref('foo')
.orderby('bar')
.endAt('foo')
.once('value')
.then(…)

@smkhalsa
Copy link

smkhalsa commented Dec 1, 2016

@auser Thanks! It looks like npm 2.3.4 fixed this for me.

@auser
Copy link
Contributor

auser commented Dec 2, 2016

@florianbepunkt it's a method on the database ref representation object, so it would happen in the then function. Using your example:

firestack
.ref('foo')
.orderby('bar').
.endAt('foo')
.once('value')
.then(ref => this.setState({items: ref.map(i => i)})); 

The map returns the ordered keys. You can handle this yourself if you want to by iterating through the keys and finding the items associated with that key and setting the order yourself or just use the map() function.

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

No branches or pull requests

6 participants