Gabriel Tiongco
Gabriel Tiongco

Reputation: 23

Firebase Android - startAt() and endAt() not working correctly?

How do I search for users based on their usernames? I have looked at numerous SO posts on this matter but am still unable to achieve what I want to do.. I have tried to apply what I saw in those posts and is shown below:

DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
            usersRef.orderByChild("username")
                    .startAt(queryText)
                    .endAt(queryText+"\uf8ff");

            usersRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {
                    searchList = new ArrayList<>();
                    for (DataSnapshot postSnapshot: snapshot.getChildren()) {
                        User user = postSnapshot.getValue(User.class);
                        Log.d("USER: ", "" + user.getUsername());

                        searchList.add(user);
                    }

                    adapter = new UserCardAdapter(getContext(), searchList);
                    recyclerView.setAdapter(adapter);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.e("onQueryTextChange: " ,databaseError.getMessage());
                }
            });

However, all users are still retrieved. I have seen the usage of startAt() and endAt() supposedly work for others on other posts but I cannot manage to get it to work for me..

This is how the user data is stored: User Data Structure

Upvotes: 1

Views: 7829

Answers (2)

weibeld
weibeld

Reputation: 15262

Your use of orderBy(), startAt(), and endAt() is correct according to the documentation.

But the addListener method must be applied directly to the object returned by the chain of orderByChild(), startAt(), and endAt() methods, and not in a new statement on the DatabaseReference retrieved with ... .getReference("users").

If you use a ChildEventListener:

DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
usersRef.orderByChild("username")
        .startAt(queryText)
        .endAt(queryText+"\uf8ff");
        .addChildEventListener(new ChildEventListener() {
          List<User> searchList = new ArrayList<>();

          @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            User user = dataSnapshot.getValue(User.class);
            Log.d("USER: ", "" + user.getUsername());
            searchList.add(user);
          }

          @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
          @Override public void onChildRemoved(DataSnapshot dataSnapshot) {}
          @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
          @Override public void onCancelled(DatabaseError databaseError) {}
    });

Upvotes: 3

Boonya Kitpitak
Boonya Kitpitak

Reputation: 3737

You almost done right but you should add addListenerForSingleValueEvent after the database reference that already apply orderBy() , startAt(), endAt() like this.

 usersRef.orderByChild("username")
                        .startAt(queryText)
                        .endAt(queryText+"\uf8ff")
                        .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {
                    searchList = new ArrayList<>();
                    for (DataSnapshot postSnapshot: snapshot.getChildren()) {
                        User user = postSnapshot.getValue(User.class);
                        Log.d("USER: ", "" + user.getUsername());

                        searchList.add(user);
                    }

                    adapter = new UserCardAdapter(getContext(), searchList);
                    recyclerView.setAdapter(adapter);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.e("onQueryTextChange: " ,databaseError.getMessage());
                }
            });

Upvotes: 3

Related Questions