Jack Wilson
Jack Wilson

Reputation: 6255

Cloud Firestore: FAILED_PRECONDITION: The query requires an index

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

Answers (5)

Yash
Yash

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

Mohammad Desouky
Mohammad Desouky

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

Gene Bo
Gene Bo

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

Arhat Baid
Arhat Baid

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.

Reference

Upvotes: 0

Jack Wilson
Jack Wilson

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

Related Questions