Cloud Firestore:FAILED_PRECONDITION:查询需要索引

时间:2018-05-07 05:01:44

标签: android firebase google-cloud-firestore

我在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());
                }
            }
        });

我收到错误,但我有一个索引。

  

获取文件时出错。       com.google.firebase.firestore.FirebaseFirestoreException:FAILED_PRECONDITION:查询需要索引。你可以创建它   这里:   https://console.firebase.google.com/project/exam-package/database/firestore/indexes?create_index=EglxYmFua2xpc3QaCQoFdmFsaWQQAhoNCgl0aW1lc3RhbXAQAxoMCghfX25hbWVfXxAD           在com.google.firebase.firestore.g.zzs.zza(SourceFile:100)           在com.google.firebase.firestore.b.zzd.zza(SourceFile:122)           在com.google.firebase.firestore.b.zzab.zza(SourceFile:333)           在com.google.firebase.firestore.b.zzf.zza(SourceFile:236)           在com.google.firebase.firestore.f.zzo.zza(SourceFile:6529)           在com.google.firebase.firestore.f.zzv.zzb(SourceFile:2089)           在com.google.firebase.firestore.f.zza $ zzb.zza(SourceFile:73)           在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)           在com.google.firebase.firestore.g.zza $ zza.run(SourceFile:190)           在java.lang.Thread.run(Thread.java:764)        引起:io.grpc.StatusException:FAILED_PRECONDITION:查询需要索引。你可以在这里创建它:   https://console.firebase.google.com/project/exam-package/database/firestore/indexes?create_index=EglxYmFua2xpc3QaCQoFdmFsaWQQAhoNCgl0aW1lc3RhbXAQAxoMCghfX25hbWVfXxAD           at io.grpc.Status.asException(Status.java:534)           在com.google.firebase.firestore.g.zzs.zza(SourceFile:98)           在com.google.firebase.firestore.b.zzd.zza(SourceFile:122)           在com.google.firebase.firestore.b.zzab.zza(SourceFile:333)           在com.google.firebase.firestore.b.zzf.zza(SourceFile:236)           在com.google.firebase.firestore.f.zzo.zza(SourceFile:6529)           在com.google.firebase.firestore.f.zzv.zzb(SourceFile:2089)           在com.google.firebase.firestore.f.zza $ zzb.zza(SourceFile:73)           在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)           在com.google.firebase.firestore.g.zza $ zza.run(SourceFile:190)           在java.lang.Thread.run(Thread.java:764)

5 个答案:

答案 0 :(得分:0)

我通过几次尝试得到了答案,

事实证明,“领域”的顺序和方向确实很重要。

在我的情况下:我建立了一个索引

FIELD1:升序

filed3:升序

它不起作用

索引必须是

FIELD2:升序

filed3:升序

FIELD1:升序

FIELD2:升序

filed3:升序

如果您使用

FIELD2:升序

filed3:降

无效。

FIELD2:升序

FIELD1:升序

filed3:升序

无效。

答案 1 :(得分:0)

我认为实地顺序并不像上面的帖子中提到的那样重要。

例如,如果您服用:

字段1:Asc 栏位2:Desc

然后它应该工作。如果在Field2上使用orderby方法,则将Query.direction明确定义为Desc。因为默认情况下是Asc。

Reference

答案 2 :(得分:0)

今天,我刚遇到这个问题,我知道我们必须为数据库创建索引。

您可以通过简单的解决方案来解决此问题。

LOG 类中的第一个显示错误消息。

例如 Log.e(TAG,task.getException()。getLocalizedMessage);

在Logcat窗口中,您将看到带有链接的消息。

单击该链接,它将打开Firebase控制台网站并显示一个用于创建索引的对话框弹出窗口。

只需点击添加索引按钮

然后刷新应用程序。它将起作用!

根据您的代码

查询查询= questionRef.whereEqualTo(“ field1”,“ content1”)
                .whereEqualTo(“ field2”,content2)
                .orderBy(“ field3”)
                .limit(LIMIT);

您似乎已为“ field3”添加了索引,但在控制台中请确保索引正确并已启用。

答案 3 :(得分:0)

为了更好地理解Firebase索引,找到了一篇不错的文章,它用一个简单的句子https://www.fullstackfirebase.com/cloud-firestore/indexes介绍了基本概念:

  

每当您要在单个查询中使用两个where子句时,Cloud Firestore中都需要索引。

..到目前为止,我还没有在Firebase官方文档中遇到过这种解释。

====

据我所知,Firebase文档开始讨论索引如何帮助提高性能,而没有解释首次有人看到的 index 实际上是什么

从google搜索的第一个结果开始: firestore理解索引 https://firebase.google.com/docs/firestore/query-data/indexing

  

Cloud Firestore通过为每个查询要求一个索引来确保查询性能。最基本查询所需的索引将自动为您创建。在使用和测试应用程序时,Cloud Firestore会生成错误消息,以帮助您创建应用程序所需的其他索引。该页面介绍了如何管理单字段索引和复合索引。

在此处共享,以防其他人也在搜索中以了解此特定细节。

答案 4 :(得分:0)

按照Firebase的建议:

Instead of defining a composite index manually, run your query in your app code to get 
a link for generating the required index.

异常消息中有一个链接,可用于创建失败的查询完全需要的特定索引