4

EDIT So after reviewing this problem with firebase developer this is working by design and there is no actual way to acheive this. Offical response from firestore dev:

Admittedly certain kinds of queries are difficult, if not feasible, when working with Firestore's NoSQL design. If the lack of such capabilities is considered a deal-breaker for your use-case, then it's likely that Firestore may not be the right database solution for you.

If you're desperate to achieve something similar then possibly this solution will work for you: https://firebase.google.com/docs/firestore/solutions/arrays#solution_a_map_of_values.

If not there is always AWS

===========================================================================

I'm noticing that the second orderBy query option does nothing to the data that is returned. Consider the following query:

firebase.firestore()
  .collection('posts')
  .orderBy('date', 'desc')
  .where('date', '>', new Date(1529802276644))
  .orderBy('rating', 'desc')
  .limit(size)

This query is intending to order posts by the date field, then filter then for the last two days, then order them by rating.

This query is currently returning 3 posts within two days, however is not sorting by rating. The results I receive are:

[
  {date: 3 hours ago, rating: 1},
  {date: 5 hours ago, rating: -1},
  {date: 9 hours ago, rating: 0},
]

And if I conduct the same query with the last orderBy removed, I actually get the exact same results:

firebase.firestore()
  .collection('posts')
  .orderBy('date', 'desc')
  .where('date', '>', new Date(1529802276644))
  .limit(size)

produces:

[
  {date: 3 hours ago, rating: 1},
  {date: 5 hours ago, rating: -1},
  {date: 9 hours ago, rating: 0},
]

I currently have an enabled index over posts. I'm fairly certain the index is correct because I was previously getting an error about a missing index before this and then fixed it with this index:

posts |  date DESC rating DESC   |    enabled

I'm pretty sure the problem lies with firebase and not with the library I'm using react-native-firebase. The firebase firestore SDK I am using is on 5.0.4 I believe

EDIT Here is how I actually use the code within my react-native project:

const episodeRef = firebase.firestore().collection('posts');
const baseRequest = episodeRef.orderBy('date', 'desc').where('date', '>', new Date(1529802276644)).orderBy('rating', 'desc').limit(25)
const documentSnapshots = await baseRequest.get()
console.log('documentSnapshots', documentSnapshots);

The console.log prints out a valid querysnapshot, and the _query field roughly looks like this:

_fieldFilters:{
    fieldPath:{
        string:"date",
        type:"string"
    },
    operator:"GREATER_THAN",
    value:{
        type:"date",
        value:1529802276644
    },
}
_fieldOrders:{
    0:{
        direction:"DESCENDING",
        fieldPath: {
            string:"date",
            type:"string"
        },
    }
    1:{
        direction:"DESCENDING"
        fieldPath:{
            string:"rating",
            type:"string"
        }
    }
}

(bad printing due to copying)

Emmett Harper
  • 239
  • 4
  • 15
  • If you're certain there's a bug, please file a bug report: https://firebase.google.com/support/contact/bugs-features/ – Doug Stevenson Jun 26 '18 at 01:49
  • @DougStevenson, I'm not certain it's a bug just looking for suggestions on what I could be doing wrong. Thanks for the link though, I'll send a report off once I'm certain! – Emmett Harper Jun 26 '18 at 01:59
  • OK, you said "pretty sure the problem lies with Firebase". If you have reproduction steps, it's not wrong to file a bug report. – Doug Stevenson Jun 26 '18 at 02:07
  • Please edit your question to include how you actually observe/handle the data. Simple `console.log()` is fine, but without that we can't know if the problem stems from such code. – Frank van Puffelen Jun 26 '18 at 03:13
  • @FrankvanPuffelen Just edited my OP with exactly how my code is handling it. I've been able to access data properly and verify simpler queries successfully before, this one just seems to be pushing the limits of what firebase can handle. Still not sure if its a bug or if it's something I'm doing wrong, can't seem to find an example of anyone else doing something like this. – Emmett Harper Jun 26 '18 at 05:00
  • 2
    While Frank van Puffelen and Doug Stevenson trying to help you it is not my place to say something but did you try any other combination to understand problem better? Like removing where clause or changing order of operations like `orderby -> orderby -> where` or `where -> orderby -> orderby` or doing just rating order – bennygenel Jun 26 '18 at 08:13
  • Thanks @bennygenel, unfortunately reordering the query with `orderby(rating) -> orderby(date) -> where(date >)` or `orderby(rating) -> where(date >) ->` throw an error about not going to work, while `orderby(date) -> orderby(rating) -> where(date >)` and `orderby(date) -> where(date >) -> orderby(rating) ` produce no error, but the date field will superseed the rating field, unless all the dates are the same. – Emmett Harper Jun 27 '18 at 05:41

1 Answers1

0

I'm not certain this is the cause, but in Firebase Realtime Database it is a common mistake, so it's worth a short here too.

When you convert the QuerySnapshot documentSnapshots to a string, it loses any information on the order of the data.

Instead loop over the results with QuerySnapshot.forEach() to ensure you maintain the order you requested the data in:

const documentSnapshots = await baseRequest.get()
documentSnapshots.forEach(document => {
  console.log('document', document);
});

If that works, this probably also works:

const documentSnapshots = await baseRequest.get()
console.log('document', documentSnapshots.docs());
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Same results, the order returned is truly `1, -1, 0`. I believe this is the intended sort by firebase since the first `date` orderBy takes precedence over the `rating` orderBy. Which is fair but a shame because I don't think I can orderBy `rating` first and then filter by `date` due to this firestore query limitation described at the bottom here: https://firebase.google.com/docs/firestore/query-data/queries – Emmett Harper Jun 27 '18 at 02:15