Monday, December 11, 2023
 Popular · Latest · Hot · Upcoming
77
rated 0 times [  80] [ 3]  / answers: 1 / hits: 7822  / 2 Years ago, mon, november 29, 2021, 12:00:00

I have a Firestore collection named channels, and I'd like to get the list of channels based on an array of IDs and order it by the createdAt field, this is my function :


  const getChannels = () => {
const q = query(
collection(db, "channels"),
where(documentId(), "in", [
"F0mnR5rNdhwSLPZ57pTP",
"G8p6TWSopLN4dNHJLH8d",
"wMWMlJwa3m3lYINNjCLT",
]),
orderBy("createdAt")
);
const unsubscribe = onSnapshot(q, (snapshot) => {
snapshot.docs.map((doc) => {
console.log(doc.data());
});
});
return unsubscribe;
};

But I'm getting this error


FirebaseError: inequality filter property and first sort order must be the same: __name__ and createdAt.


It only works if I orderBy documentId().


I'm aware there is a limitation in the docs about this, but I'm wondering if there is a workaround for this type of situation.


Also the answer for this question isn't working anymore I guess.


More From » reactjs

 Answers
0

The title of your question indicates that you are trying to use where and orderBy for different fields. But note that you are using documentId() in the where condition to filter, which is not a field in the Firestore document.


So if you filter is based on documentId(), you can use only documentId() in orderBy() clause, that also in ascending order because currently Firestore does not support sorting in descending order of documentId() which is mentioned in this answer.


Let’s take a look at the following examples -


const data=await db.collection("users").where(admin.firestore.FieldPath.documentId(),"in",["104","102","101"]).orderBy(admin.firestore.FieldPath.documentId()).get();

The above will work and sort the documents based on documentId() after filtering based on documentId().
But it is not relevant to apply an orderBy() clause based on the documentId(), because without applying the orderBy() clause also yields the same result as, by default, Firestore query gives documents in ascending order of documentId(). That means the following also yields the same result -


const data=await db.collection("users").where(admin.firestore.FieldPath.documentId(),"in",["104","102","101"]).get();

Now Firestore doesn’t support to sort in descending order of documentId() which means the following will not work -


const data=await db.collection("users").where(admin.firestore.FieldPath.documentId(),"in",["104","102","101"]).orderBy(admin.firestore.FieldPath.documentId(),"desc").get();

This will ask to create an index -


The query requires an index. You can create it here:

But if you go there to create an index it will say -


__name__ only indexes are not supported.

Now let's come to your query. What you are trying to do is to filter based on documentId() and then orderBy() based on createdAt field which is not possible and it will give the following error-


inequality filter property and first sort order must be the same.

You may think to use two orderBy() clauses, something like this -


const data=await db.collection("users").where(admin.firestore.FieldPath.documentId(),"in",["104","102","101"]).orderBy(admin.firestore.FieldPath.documentId()).orderBy(“createdAt”
).get();

Which will not work and give the following error


order by clause cannot contain more fields after the key

I am not sure of your use case but it’s not a great idea to filter based on documentId(). If it is required to filter based on documentId(), I would suggest creating a field in the Firestore document which will contain the documentIds and filter based on that.


Now considering the title of the question, yes it is possible to use where() and orderBy() clauses for different fields in Firestore. There are some limitations and you need to stick to that -



If you include a filter with a range comparison (<, <=, >, >=), your first ordering must be on the same field.



const data=await db.collection("users").where(“number”,">=", “101”).orderBy(“createdAt”).get(); 

The above query doesn't work.


const data=await db.collection("users").where(“number”,">=", “101”).orderBy(“number”).get(); 

The above query works and you can still use further orderBy() on different fields, something like following -


const data=await db.collection("users").where(“number”,">=", “101”).orderBy(“number”).orderBy(“createdAt”).get(); 


You cannot order your query by any field included in an equality (=) or in clause.



const data=await db.collection("users").where(“number”,"in",["104","102","101"]).orderBy(“number”).get();
const data=await db.collection("users").where(“number”,"==", “101”).orderBy(“number”).get();

The above two don’t work.


[#637] Monday, November 22, 2021, 2 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
monicag

Total Points: 651
Total Questions: 106
Total Answers: 104

Location: Grenada
Member since Sun, Dec 20, 2020
3 Years ago
monicag questions
;