Reputation: 6255
I made a query in Cloud Firestore,
CollectionReference questionRef = db.collection("collectionName");
Query query = questionRef.whereEqualTo("field1", "content1")
.whereEqualTo("field2",content2)
.orderBy("field3")
.limit(LIMIT);
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>()
{
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task)
{
if (task.isSuccessful())
{
for (DocumentSnapshot document : task.getResult())
{
Log.d(TAG, document.getId() + " => " + document.getData());
}
}
else
{
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
and I received errors, but I had an index.
Error getting documents. com.google.firebase.firestore.FirebaseFirestoreException: FAILED_PRECONDITION: The query requires an index. You can create it here: https://console.firebase.google.com/project/exam-package/database/firestore/indexes?create_index=EglxYmFua2xpc3QaCQoFdmFsaWQQAhoNCgl0aW1lc3RhbXAQAxoMCghfX25hbWVfXxAD at com.google.firebase.firestore.g.zzs.zza(SourceFile:100) at com.google.firebase.firestore.b.zzd.zza(SourceFile:122) at com.google.firebase.firestore.b.zzab.zza(SourceFile:333) at com.google.firebase.firestore.b.zzf.zza(SourceFile:236) at com.google.firebase.firestore.f.zzo.zza(SourceFile:6529) at com.google.firebase.firestore.f.zzv.zzb(SourceFile:2089) at com.google.firebase.firestore.f.zza$zzb.zza(SourceFile:73) at com.google.firebase.firestore.g.zzm$1.onMessage(SourceFile:77) at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:36) at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:36) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:498) at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at com.google.firebase.firestore.g.zza$zza.run(SourceFile:190) at java.lang.Thread.run(Thread.java:764) Caused by: io.grpc.StatusException: FAILED_PRECONDITION: The query requires an index. You can create it here: https://console.firebase.google.com/project/exam-package/database/firestore/indexes?create_index=EglxYmFua2xpc3QaCQoFdmFsaWQQAhoNCgl0aW1lc3RhbXAQAxoMCghfX25hbWVfXxAD at io.grpc.Status.asException(Status.java:534) at com.google.firebase.firestore.g.zzs.zza(SourceFile:98) at com.google.firebase.firestore.b.zzd.zza(SourceFile:122) at com.google.firebase.firestore.b.zzab.zza(SourceFile:333) at com.google.firebase.firestore.b.zzf.zza(SourceFile:236) at com.google.firebase.firestore.f.zzo.zza(SourceFile:6529) at com.google.firebase.firestore.f.zzv.zzb(SourceFile:2089) at com.google.firebase.firestore.f.zza$zzb.zza(SourceFile:73) at com.google.firebase.firestore.g.zzm$1.onMessage(SourceFile:77) at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:36) at io.grpc.ForwardingClientCallListener.onMessage(ForwardingClientCallListener.java:36) at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:498) at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at com.google.firebase.firestore.g.zza$zza.run(SourceFile:190) at java.lang.Thread.run(Thread.java:764)
Upvotes: 22
Views: 42281
Reputation: 542
I got this issue and I came to know that we have to create the index for database.
You can fix this via simple solution.
First display error message in LOG Class.
e.g. Log.e(TAG, task.getException().getLocalizedMessage);
In the Logcat window you will see the message with link.
Click on that link, It will open firebase console website and display one Dialog popup for create index.
Just click on Add index button.
Then refresh the app. It will work!
And As per your code:
Query query = questionRef.whereEqualTo("field1", "content1")
.whereEqualTo("field2",content2)
.orderBy("field3")
.limit(LIMIT);
It looks like you have added index for "field3", but in the console make sure that index is correct and enabled.
Upvotes: 26
Reputation: 764
as firebase recommends:
Instead of defining a composite index manually, run your query in your app code to get
a link for generating the required index.
the exception message has a link to create a specific index which exactly required by your failed query
Upvotes: 4
Reputation: 12103
In trying to understand Firebase indexes better, found a good article that introduces the basic idea in one simple sentence, https://www.fullstackfirebase.com/cloud-firestore/indexes :
Indexes are required in Cloud Firestore whenever you want to use two where-clauses in a single query.
.. an explanation that so far, I haven't run across in the official Firebase docs.
====
Far as I can tell, Firebase docs start discussing how indexes help performance, without explanation of what index actually is for someone seeing it for the first time.
From the first result in a google search on: firestore understanding indexes https://firebase.google.com/docs/firestore/query-data/indexing
Cloud Firestore ensures query performance by requiring an index for every query. The indexes required for the most basic queries are automatically created for you. As you use and test your app, Cloud Firestore generates error messages that help you create additional indexes your app requires. This page describes how to manage your single-field and composite indexes.
Sharing here in case others are as well on the search to understand this particular detail.
Upvotes: 19
Reputation: 1023
I don't think the field order matters the way it is mentioned in the above post.
For instance if you take:
Field1: Asc Field2: Desc
then it should work. If you are using the orderby method on Field2 then explicitly define the Query.direction as Desc. Because it's Asc by default.
Upvotes: 0
Reputation: 6255
I got the answer through several tries,
It turns out to be the "field" order and direction really matters.
in my case: I built an index
field1:ascending
filed3:ascending
it doesn't work
The index must be
field2:ascending
filed3:ascending
or
field1:ascending
field2:ascending
filed3:ascending
If you used
field2:ascending
filed3:descending
won't work.
or
field2:ascending
field1:ascending
filed3:ascending
won't work.
Upvotes: 1