1

I try to integrate search in Firestore collections, using letters that I typed in EditText. I mean, how can I make this without any buttons, just realtime searching, that is when I type any letters in EditText and results are appear in the ListView.

My class, where I retrived all records from Firestore:

public class AllPlaces extends AppCompatActivity {

private EditText eName;
private ListView mList;

private FirebaseFirestore firestore = FirebaseFirestore.getInstance();
private CollectionReference reference = firestore.collection("Users");
private SearchAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_all_places);

    mList = findViewById(R.id.listSearch);
    eName = findViewById(R.id.editSearch);

    reference.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            List<SearchModel> names = new ArrayList<>();
            if(task.isSuccessful()){
                for(QueryDocumentSnapshot document : task.getResult()) {
                    SearchModel model = document.toObject(SearchModel.class);
                    names.add(model);
                }
                mList = findViewById(R.id.listSearch);
                adapter = new SearchAdapter(AllPlaces.this, names);
                mList.setAdapter(adapter);
            }
        }
    });
}
}

UPDATE:

I found this solution, but it didn't work correctly, when I type some letter - all information is disappearing from the ListView:

eName.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                    }

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {

                        AllPlaces.this.adapter.getFilter().filter(s);
                    }

                    @Override
                    public void afterTextChanged(Editable s) {

                    }
                });
Spike Johnson
  • 365
  • 4
  • 12
  • 1
    You can take a look **[here](https://stackoverflow.com/questions/49596610/is-it-possible-to-use-algolia-query-in-firestorerecycleroptions/49607796)**. – Alex Mamo Jun 25 '18 at 08:19

1 Answers1

6
private FirebaseFirestore firestore = FirebaseFirestore.getInstance();
private CollectionReference reference = firestore.collection("Users");
Query q;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_all_places);

    q = firestore.collection("Users");
    showAdapter(q);

eName.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        if (charSequence.toString().length() == 0) {
            q = firestore.collection("Users");
            showAdapter(q);
         } // This is used as if user erases the characters in the search field.
         else {
             q = reference.orderBy("name").startAt(charSequence.toString().trim()).endAt(charSequence.toString().trim() + "\uf8ff"); // name - the field for which you want to make search
             showAdapter(q);
          }
          adapter.notifyDataSetChanged();
    }
    @Override
    public void afterTextChanged(Editable editable) {
    }
});

void showAdapter(Query q1) {
    q1.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            List<SearchModel> names = new ArrayList<>();
            if(task.isSuccessful()){
                for(QueryDocumentSnapshot document : task.getResult()) {
                    SearchModel model = document.toObject(SearchModel.class);
                    names.add(model);
                }
                mList = findViewById(R.id.listSearch);
                adapter = new SearchAdapter(AllPlaces.this, names);
                mList.setAdapter(adapter);
            }
        }
    });
}

I hope this will help ..

Raj
  • 2,997
  • 2
  • 12
  • 30
  • There are some progress, tnaks for that! But it work good, when I type any letters, when I delete letters, listview doesn't back in normal view - there are become empty.@Raj – Spike Johnson Jun 24 '18 at 08:17
  • I have added that case too. ( Mentioned clearly in comments). Also method will be called every time when text is changed. So you should wait to fetch the result. You should check once. So you should accept and upvote the answer which can be helpful for others too. – Raj Jun 24 '18 at 08:27
  • Yes, this works when you type 2 letters for example, and delete one of them - the result changes - i't all good, but doesn't work, when you delete all letters, in this case - is empty..@Raj – Spike Johnson Jun 24 '18 at 08:54
  • To be currently - after deleting all letters in EditView - it stay the last search result, that was before this.. – Spike Johnson Jun 24 '18 at 08:55
  • Big thanks @Raj! I got it. Is this right, to make that case of letters isn't taken, I must use .toLowerCase(), .toUpperCase()? – Spike Johnson Jun 25 '18 at 13:06
  • 3 years old but still relevant. Thank you so much. – Patrick Aug 13 '21 at 05:42