【问题标题】:Android: Firebase Search Query not working properlyAndroid:Firebase 搜索查询无法正常工作
【发布时间】:2019-01-12 00:01:07
【问题描述】:

我对 Android 应用开发相当陌生。我创建了一个简单的搜索查询,按名称搜索我的 firebase 数据库(请参见下面的代码):

private void firebaseEventSearch(String name) {
    //query to search database based on text in textbox - made case insensitive
    Query eventSearchQuery = eventRef.orderByChild("name").startAt(name.toUpperCase()).endAt(name.toLowerCase() + "\uf8ff");
    eventSearchQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
                Event event = eventSnapshot.getValue(Event.class);
                events.add(event);
            }
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

它在大多数情况下都可以正常工作,但是,当我输入字母“A”或“B”时,它将显示所有数据库结果——搜索不适用于这两个字母。此外,如果我输入第一个字母与数据库条目匹配的搜索字符串,它将显示此数据库项,即使字符串的其余部分不匹配。

如果有人能帮助我理解为什么这个搜索查询不能正常工作,我将不胜感激。

【问题讨论】:

  • "另外,如果我输入第一个字母与数据库条目匹配的搜索字符串,它将显示此数据库项目,即使字符串的其余部分不匹配。"这种行为似乎与您实现的代码完全一致。您正在过滤以输入的搜索字符串开头的任何项目。如果您想要不同的行为,则需要执行不同的查询。例如,您不是在寻找eventRef.orderByChild("name").equalTo(name)。
  • 您好弗兰克,感谢您的回答。我的问题是,如果我的搜索字符串是“cu”,它仍然会显示以“co”或“ca”等开头的数据库结果,即使这在技术上与搜索字符串不匹配。你知道有没有办法解决这个问题?
  • 如果即使有了我的回答您仍然遇到问题,请将您的问题更新为:1) 为 name 使用硬编码值 2) 包含来自 eventRef 的 JSON(作为文本,没有截图)。您可以通过单击Firebase Database console 上溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。

标签: java android firebase firebase-realtime-database


【解决方案1】:

Firebase 中的查询对大写字母非常敏感。试试这个。

private void firebaseEventSearch(String name) {
    //query to search database based on text in textbox - made case insensitive
    //Add this part
    String firstLetterCapital = query.substring(0, 1).toUpperCase() + query.substring(1);
    Query eventSearchQuery = eventRef.orderByChild("name").startAt(firstLetterCapital).endAt(firstLetterCapital + "\uf8ff");
    eventSearchQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
                Event event = eventSnapshot.getValue(Event.class);
                events.add(event);
            }
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

【讨论】:

  • 非常感谢您的帮助!添加后,我的查询将不会返回只有第一个字母匹配的值。但是,我仍然对字母“a”和“b”有疑问......有什么想法吗?
  • @minikate 我可以知道events 来自哪里吗?
  • "events" 是一个数组列表,将各个数据库项添加到其中。 List<Event> events = new ArrayList<>();
  • @minikate 你在使用 firebase 回收器适配器吗?
  • 我使用的是 RecyclerView,然后是这个适配器:EventAdapter adapter = new EventAdapter(this, R.layout.eventlist_layout, events);
【解决方案2】:

Firebase 数据库查询区分大小写。因此,当您调用 orderByChild("name") 时,所有节点都按其 name 属性排序。如果您查看 ASCII 图表,您会发现这将导致小写和大写字符的顺序如下:

A B C .... X Y Z a b c ... x y z

现在,您的查询获取了这些数据的一部分。如果您正在搜索A,则切片为:

A B C .... X Y Z a

所以这比你想要的要多。

如果您想在 Firebase 上允许不区分大小写的搜索,最常见(但不是完全故障安全)的实现方式是添加一个额外的属性,该属性以不区分大小写的方式存储名称。例如。 "name_uppercase": "ZUHRAIN"。有了它,您可以搜索:

eventRef.orderByChild("name_uppercase").startAt(name.toUpperCase()).endAt(name.toUpperCase() + "\uf8ff");

另见:

【讨论】:

  • 先生,可以为大写创建一个新的孩子吗?示例:.child(uid).child("upperCase").setValue(modelUserUpperCase);
  • 是的,这实际上是我的回答所提倡的。 name_uppercase 是一个附加属性,它应该包含 name 的全大写值。
  • @FrankvanPuffelen 但如何显示查询?我的意思是现在我们可以正常显示,不用大写。例如:.child("user").orderByChild("name") ...。然后,如何处理大写,因为它们都在子“大写”中。
  • 抱歉,我很难理解问题所在。您可以通过名称访问name 或name_uppercase 属性。如果您在实施时遇到困难,请使用minimal code that reproduces that problem 提出一个新问题。
猜你喜欢
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
  • 2021-11-10
  • 2017-01-28
  • 2013-12-23
  • 2015-07-27
相关资源
最近更新 更多