Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Firebase Search Query not working properly

I am fairly new to Android app development. I have created a simple search query that searches my firebase database by name (see code below):

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) {

        }
    });
}

It works fine for the most part, however, it will display all database results when I type in the letters "A" or "B" - the search does not work for these two letters. Also, if I type in a search string where the first letter matches a database entry, it will display this database item, even if the rest of the string does not match it.

I would really appreciate if anyone could help me understand why this search query is not working properly.

like image 489
minikate Avatar asked Jan 12 '19 00:01

minikate


2 Answers

Query in Firebase is really sensitive with the capital letter. Try this one.

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) {

        }
    });
}
like image 136
Ticherhaz FreePalestine Avatar answered Sep 20 '22 09:09

Ticherhaz FreePalestine


Firebase Database queries are case-sensitive. So when you call orderByChild("name") all nodes are ordered by their name property. If you look at an ASCII chart, you'll see that this will lead to this order for lowercase and uppercase characters:

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

Now your query takes a slice of this data. If you're searching for A, the slice is:

A B C .... X Y Z a

So that's way more than you want.

If you want to allow case-indifferent search on Firebase, the most common (but not completely failsafe) way to implement it is to add an extra property that stores the name in an case-indifferent way. E.g. "name_uppercase": "ZUHRAIN". With that you can search on:

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

Also see:

  • Making a firebase query search NOT case sensitive
  • firebase query methods startAt() taking case sensitive parameters
  • Cloud Firestore Case Insensitive Sorting Using Query (for Cloud Firestore, but it shows a more failsafe way to do this)
like image 39
Frank van Puffelen Avatar answered Sep 20 '22 09:09

Frank van Puffelen