Android Firebase QuerySnapshot为复合查询返回null
对于我的应用程序,我实现了一个过滤器选项。我使用FirebaseAndroid Firebase QuerySnapshot为复合查询返回null,android,firebase,google-cloud-firestore,Android,Firebase,Google Cloud Firestore,对于我的应用程序,我实现了一个过滤器选项。我使用Firebase查询来使用所述过滤器进行查询。以下是实现: private void loadDestinations() { Query query = App.getFirestore().collection("destinations"); if (mFilters.hasCountry()) { query = query.whereEqualTo(Destination.FIELD_COUNTRY, m
查询
来使用所述过滤器进行查询。以下是实现:
private void loadDestinations() {
Query query = App.getFirestore().collection("destinations");
if (mFilters.hasCountry()) {
query = query.whereEqualTo(Destination.FIELD_COUNTRY, mFilters.getCountry());
}
if (mFilters.hasPrice()) {
query = query.whereEqualTo(Destination.FIELD_PRICE, mFilters.getPrice());
}
if (mFilters.hasSortBy()) {
query = query.orderBy(mFilters.getSortBy(), mFilters.getSortDirection());
}
query.addSnapshotListener((documentSnapshots, e) -> {
if (documentSnapshots != null) {
if (!documentSnapshots.isEmpty()) {
Log.d(LOG_TAG, "Snapshots are not null and have value");
List<Destination> destinationList = documentSnapshots.toObjects(Destination.class);
mDestinations.setValue(destinationList);
} else {
Log.d(LOG_TAG, "Snapshots are not null but have no value");
mDestinations.setValue(new ArrayList<>());
}
} else {
Log.e(LOG_TAG, "Snapshots are NULL!");
mDestinations.setValue(new ArrayList<>());
}
});
}
private void loadDestinations(){
Query Query=App.getFirestore().collection(“目的地”);
if(mFilters.hasCountry()){
query=query.whereEqualTo(Destination.FIELD_COUNTRY,mFilters.getCountry());
}
if(mFilters.hasPrice()){
query=query.whereEqualTo(Destination.FIELD_PRICE,mFilters.getPrice());
}
if(mFilters.hasSortBy()){
query=query.orderBy(mFilters.getSortBy(),mFilters.getSortDirection());
}
query.addSnapshotListener((DocumentSnapshot,e)->{
if(documentSnapshots!=null){
如果(!documentSnapshots.isEmpty()){
Log.d(Log_标记,“快照不为空且有值”);
List destinationList=documentSnapshots.toObjects(Destination.class);
mdestations.setValue(destinationList);
}否则{
Log.d(Log_标记,“快照不为空但没有值”);
setValue(新的ArrayList());
}
}否则{
Log.e(Log_标记,“快照为空!”);
setValue(新的ArrayList());
}
});
}
看看第二行,我在那里实例化了查询
对象。然后,我对用户添加的每种类型的过滤器(国家、价格、排序)进行复合
现在,如果我将国家/地区和价格组合起来,这将非常好地加载,但只要添加排序akaquery.orderBy()
,第17行的文档快照就会返回null。更奇怪的是,如果使用复合查询,snapshotListener会检索两次数据。第一次登录时:
快照不为null且具有值
然后紧接着它记录下来
快照为空
即使调用了一次loadDestinations()
方法(我选中了)
我肯定地知道,大约一个月前,这不是一个问题,因为那时我开发了这个部分并测试了它。但现在,出于某种原因,它正以这种方式行事。API是否有任何重大变化?代码有错吗
额外:比如,在第2行,我添加了另一个。whereEqualTo()
如下:
Query Query=App.getFirestore().collection(“目的地”).whereEqualTo(“已批准”,true)代码>
侦听器将返回空值,只添加一个筛选器(而不是之前的两个)。我之所以提到这一点,是因为我认为这与数据的排序方式无关,更重要的是,复合查询不起作用。出于某种原因,它会第二次重试,直到为null。我也不认为这是关于创建索引的,因为我一个月前就已经这样做了。另外,它在日志中也会提到同样多的内容。我怀疑发生的情况是,在一个字段上执行“等于”查询,再在另一个字段上执行“排序方式”,需要创建一个复合索引才能运行此查询
通常,您会获得URL来在error对象中创建此自定义索引,因此我强烈建议您检查并记录error对象的内容
(即使这不是原因,但养成检查错误对象的习惯始终是个好主意。这可能会帮助您避免将来出现一系列神秘的错误。)我怀疑正在发生的事情是在一个字段上执行“等于”查询加上“排序方式”在另一个字段上,需要创建复合索引才能运行此查询
通常,您会获得URL来在error对象中创建此自定义索引,因此我强烈建议您检查并记录error对象的内容
(即使这不是原因,也最好养成检查错误对象的习惯。这可能有助于避免将来出现一系列神秘的错误。)生成器模式有点难以解析。您是否可以将代码简化为最简单的查询(字段名和值只有硬编码的值)而不返回任何内容,而您认为它应该返回一些内容?然后,您是否也可以显示您正在查询的相应文档/集合结构的屏幕截图?@FrankvanPuffelen我已经用请求的信息更新了问题。您是否可以确认,在正常操作下,返回的QuerySnapshot
将永远不会为空?即使查询没有找到文档。据我所知,确实应该总是有一个QuerySnapshot
。它可能只是不包含数据/结果。您似乎没有检查或打印错误对象的内容。你能做到吗?我怀疑这里发生的事情是,您遇到了一个需要与复合索引一起使用的查询,但是您没有得到该消息,因为您没有进行任何错误检查。生成器模式有点难以解析。您是否可以将代码简化为最简单的查询(字段名和值只有硬编码的值)而不返回任何内容,而您认为它应该返回一些内容?然后,您是否也可以显示您正在查询的相应文档/集合结构的屏幕截图?@FrankvanPuffelen我已经用请求的信息更新了问题。您是否可以确认,在正常操作下,返回的QuerySnapshot
将永远不会为空?即使查询没有找到文档。据我所知,确实应该总是有一个QuerySnapshot
。它可能只是不包含数据/结果。您似乎没有检查或打印错误对象的内容。你能做到吗?我怀疑这里发生的事情是,您遇到了一个需要与复合索引一起使用的查询,但您没有得到该消息,因为您