-1

I am storing a list of users in Firebase. The structure looks like this:

enter image description here

In my Android app, I want to let the user search for any user in a flexible manner. So John Smith should show up in the results if the user searches for things like: Joh..., Smit..., jsmi.... Also, I want the search to show results instantly as the user types (like Instagram).

Currently, this is my implementation. I pull all the user details when the search activity opens up and store all details in an ArrayList. Then when user starts searching, I search the ArrayList and returns the matches.

Below is some sample code:

ArrayList<User> listOfUsers = new ArrayList<>();

ref.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
      User user = userSnapshot.getValue(User.class);
      listOfUsers.add(user);
    }
  }

  @Override
  public void onCancelled(DatabaseError databaseError) { }
});

// Then I search for users like this
for (User user : listOfUsers) {
   if (user.getFullname.contains("Joh") || 
      user.getUsername.contains("Joh")){
      // show user in results
   }
}

It works fine right now because I don't have too many users. But I feel that if I have 100k users, pulling all their details before hand and parsing the arrayList of 100k items to look for matches might be expensive. What would be a better solution?

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Parth Bhoiwala
  • 1,282
  • 3
  • 19
  • 44
  • if you are looking for suggestions for a better search performance, I'll suggest you use a 3rd party service like algolia search – danijax May 07 '18 at 20:25
  • May I know why my question was downvoted? I provided the structure I was using and also provided sample code of my current implementation. – Parth Bhoiwala May 08 '18 at 13:35

1 Answers1

1

Firebase doesn't support native indexing or search for text fields in the database. Additionally, downloading an entire node to search for fields client-side isn't practical, most of the time because of the size.

Unfortunately, Firebase also doesn't allow you to create a search on more than one property. So a query like this is not allowed.

usersRef
    .whereEqualTo("name", "John Smith")
    .whereEqualTo("username", "jsmith"); //Not allowed

But if you want to query your database based on a single property for things like: Joh... but not Smit..., a query like this required:

usersRef
    .whereEqualTo("name", "Joh")
    .startAt(searchText).endAt(searchText + "\uf8ff");

If you want to use an newer version of the database, I recommend try Cloud Firestore. To enable full text search of your Cloud Firestore database you can use a third-party search service named Algolia, that will help you achieve the exact thing that you want. And for that I recommend you see my answer from this post. For more information, I also recommend you see this video.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Thanks for the suggestion. I have looked into Firestore. It's good but doesn't allow the flexibility that Firebase Database allows. And I have heard about Algolia, but at this point, I can't afford to pay for their service. – Parth Bhoiwala May 08 '18 at 13:36
  • "I have looked into Firestore. It's good but doesn't allow the flexibility that Firebase Database allows." Luckily is does and even more than that and that's why I suggested you this options. Using only Firebase Realtime database you cannot achieve that. – Alex Mamo May 08 '18 at 13:42
  • Is there everything alright? Can I help you with other informations? – Alex Mamo May 09 '18 at 08:06