3
votes

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)

1
If you're certain there's a bug, please file a bug report: firebase.google.com/support/contact/bugs-featuresDoug Stevenson
@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
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
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
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 orderbennygenel

1 Answers

0
votes

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());