0

In my ExploreFragment.java I have an EditText which basically allows the user to search country names that are stored in my Firebase Realtime Database. What I want to achieve is, when the user types something in the EditText and then presses "submit" in their keyboard, it makes a query that retrieves every country which has the string they typed in their name, and get redirected to my fragment FilteredResultsFragment.java which displays the names of the countries retrieved. My fragment has a recycler view with an Adapter. I haven't achieved this yet. I need to retrieve a List with the urls and a List with the names. The query should look like this:

FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
Log.d("TAMANHO","size = "+paisEscolhido.size());
for (int i = 0; i<paisEscolhido.size(); i++) {
    Log.d("CONTINETNE","size = "+paisEscolhido.get(i));
    DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
    Query queries = paisNomeContinentes.orderByChild("Continente").equalTo(paisEscolhido.get(i));

    queries.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
      @Override
      public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        List<String> imagemPaisList = new ArrayList<>();
        List<String> nomePaisList = new ArrayList<>();
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            String imagemPais = ds.child("Imagem").getValue(String.class);
            String nomePais = ds.child("Nome").getValue(String.class);
            imagemPaisList.add(imagemPais);
            nomePaisList.add(nomePais);
        }
        int urlCount = imagemPaisList.size();

        //  int randomImage = new Random().nextInt(urlCount);

        for (int i = 0; i < nomePaisList.size(); i++) {

                Integer randomVariavel = new Random().nextInt(urlCount);

                randomImagemPaisList.add(imagemPaisList.get(randomVariavel));
                randomNomePaisList.add(nomePaisList.get(randomVariavel));

        }

UPDATE

I've come up with this query:

FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference paisNomeContinentes = mDatabase.getReference().child("paises");
Query queries = paisNomeContinentes.orderByChild("Nome").startAt("Po");

queries.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

        List<String> imagemPaisList = new ArrayList<>();
        List<String> nomePaisList = new ArrayList<>();
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            String imagemPais = ds.child("Imagem").getValue(String.class);
            String nomePais = ds.child("Nome").getValue(String.class);
            imagemPaisList.add(imagemPais);
            nomePaisList.add(nomePais);
        }
    }

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

That should retrieve the Name of the country that starts with the value the user writes in my EditText but, when I write, for example "Po", it should give me "Portugal" and "Poland" but, instead, it gives me random images...

This is the data structure:

enter image description here

UPDATE V2 It actually gives me "Poland" and "Portugal" as the top results but it shows my more ImageView besides those two (and with random images too)...

André Silva
  • 121
  • 11
  • Firebase cannot query for strings that **contain** a value. It can only query for strings that **start with** that value. Does that explain what you're seeing happen when you run this code? – Frank van Puffelen Jul 08 '18 at 13:15
  • Hm, so if I save a variable with the value of EditText and query it like that but change the "equalTo" to "startWith(variable)" I will get all the countries that start with those characters? – André Silva Jul 08 '18 at 18:28
  • @FrankvanPuffelen Please, see my updated question :) – André Silva Jul 08 '18 at 20:06
  • You can filter by 'x' in your firebase adapter. Just hide item view that you dont want to display that item – Ozan Jul 08 '18 at 20:08
  • Please simplify your code, as there is too much going on in there right now. 1) Remove all the manipulation of views, 2) remove all the lists, 3) use hardcoded values for the search string, 4) use simple log statements to write the value that is not what you expect, 5) show the data structure that you query, 6) show the output of the log statements. With that it should be possible to reproduce the problem in a dozen lines or so. – Frank van Puffelen Jul 08 '18 at 23:09
  • @FrankvanPuffelen Ok, I've updated my question and removed a lot of trash code :) Hope it helps ;) – André Silva Jul 09 '18 at 07:54
  • Can you take a look at [this question](https://stackoverflow.com/q/50715093/4916627)? I think that's the same thing that is happening here. – André Kool Jul 09 '18 at 08:36
  • @AndréKool Hm.. So I need to use `endAt()`? And what do I put inside `endAt`? – André Silva Jul 09 '18 at 08:39
  • The searchquery you are using in your `startAt()` + `\uf8ff`. That will limit your query to every child that starts with your searchquery. – André Kool Jul 09 '18 at 08:42
  • So, in my case, it would be `endAt(String.valueOf(srcView.getText()))+"\utf8ff"`? It's giving me an error saying `illegal escape in character in string literal` in "\utf8" – André Silva Jul 09 '18 at 08:45
  • @AndréKool Nevermind. I misspelled `uf8` with `utf8` ahah – André Silva Jul 09 '18 at 09:01
  • So it is working now? If it is I will write it up in an answer :) – André Kool Jul 09 '18 at 09:01
  • @AndréKool Yup! You can write so I can upvote ;) – André Silva Jul 09 '18 at 09:07

1 Answers1

2

If you want to use startAt() to filter your data you also have to use endAt() because startAt() works as a starting point for your query and not a filter. By adding \uf8ff (the last unicode character) behind your searchstring in endAt() you limit your query to get only the values that start with your searchstring:

Query queries = paisNomeContinentes.orderByChild("Nome").startAt("Po").endAt("Po" + "\uf8ff");

Just remember this will only get the items that start with the searchstring, not the items that contain the searchstring.

André Kool
  • 4,880
  • 12
  • 34
  • 44
  • Mate, sorry for bothering you once again, but, how do I cast the first letter to be always Upper? I mean, when the user types "portu" it's different from when he types "Portu" ahaha – André Silva Jul 09 '18 at 15:02
  • @AndréSilva https://stackoverflow.com/questions/5725892/how-to-capitalize-the-first-letter-of-word-in-a-string-using-java – André Kool Jul 09 '18 at 15:08