FirestoreRecyclerOptions。当不需要索引时,查询需要索引错误。仅当我使用orderBy时

时间:2020-02-20 19:26:17

标签: android firebase google-cloud-firestore

我正在使用Firestore数据库和FirebaseUI将结果加载到android kotlin中的回收器视图中。我遇到了一些奇怪的事情。

当在不同的字段上进行太多不同的请求时,我理解错误“查询需要索引”。但是,我知道您可以发出许多请求whereEqualTo以及一个请求orderBy。现在,当我自己发出此请求时(不使用FirestoreRecyclerOptions)。我没问题,效果很好。

但是,当我将请求与FirestoreRecyclerOptions一起使用时,例如:

 var querySearch = FirebaseFirestore.getInstance()
            .collection(DB_DEALS_COLLECTION).document(departureCountry.toString()).collection(DB_DEALS_SUB_COLLECTION)
            .whereEqualTo(FILTER_FIELD_APR, true)
            .whereEqualTo(FILTER_FIELD_AUG, true)
            .whereEqualTo(FILTER_FIELD_DEC, true)
            .orderBy(FILTER_FIELD_TIMESTAMP, Query.Direction.DESCENDING).limit(15)

        val options = FirestoreRecyclerOptions.Builder<Deal>().setQuery(querySearch, Deal::class.java).build()

我收到此错误:

[Firestore]: Listen for Query(target=Query(deals_collection/USA/deals where monthApr == true and monthAug == true and monthDec == true order by -timestamp, -__name__);limitType=LIMIT_TO_FIRST) failed: Status{code=FAILED_PRECONDITION, description=The query requires an index.

现在,有两件事很奇怪: 1.根据我的检查,实际上我的recyclerview中显示了正确的结果。但我担心为什么收到此消息,并且我不想将来出现不正确的结果。 2.当我单击控制台中的链接以添加索引时,我在Firestore控制台中得到以下消息以添加:我必须使用以下字段创建一个复合索引:

monthApr Ascending 
monthAug Ascending 
monthDec Ascending 
timestamp Descending

现在我再也不想让这些字段递增,仅是时间戳记?

注意:只有在包含以下内容时才会发生这种情况:

.orderBy(FILTER_FIELD_TIMESTAMP, 

我也在控制台中看到limitType=LIMIT_TO_FIRST。我也看到-__name__。这些是什么,我从没设置过!

我希望我的问题很清楚,我对此感到有点困惑。

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您的查询确实需要索引,则应该可以通过覆盖FirebaseRecyclerAdapter中的the error callback来轻松创建它:

FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<T, H>(options) {
   // ... 

    @Override
    public void onError(@NonNull FirebaseFirestoreException e) {
        Log.w(TAG, "onError", e);
    }
};

然后在您的logcat中,您将看到完整的错误,其中包括一个链接,您可以单击该链接来自动创建丢失的索引。

关于您的其他问题:

  • 您是否从同一设备创建数据?如果是这样,那就可以解释为什么尽管有错误,您仍然在RecyclerView中看到数据。它来自不使用索引的脱机缓存。
  • .limit(15).limitToFirst(15)的较不冗长的说法。因此您可以忽略limitType=LIMIT_TO_FIRST
  • __name__是文档ID的特殊保留字段。您所做的每个查询最后都按__name__进行排序,这样即使您的其他orderBy子句上有平局,您也始终会以相同的顺序获得结果。