1

I tried to make this:

My user model:

public class User {

private String id;
private String username;
private String imageurl;
private String bio;

public User(String id, String username, String imageurl, String bio) {
    this.id = id;
    this.username = username;
    this.imageurl = imageurl;
    this.bio = bio;
}
public User(){
}
public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
public String getImageurl() {
    return imageurl;
}
public void setImageurl(String imageurl) {
    this.imageurl = imageurl;
}
public String getBio() {
    return bio;
}
public void setBio(String bio) {
    this.bio = bio;
}}

This is the user adapter:

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder>{

private Context mContext;
private List<User> mUsers;
private FirebaseUser firebaseUser;

public UserAdapter(Context mContext, List<User> mUsers) {
    this.mContext = mContext;
    this.mUsers = mUsers;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(mContext).inflate(R.layout.user_item,parent,false);
    return new UserAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    firebaseUser=FirebaseAuth.getInstance().getCurrentUser();
    final User user = mUsers.get(position);
    holder.btn_follow.setVisibility(View.VISIBLE);
    holder.username.setText(user.getUsername());
    Picasso.get().load(user.getImageurl()).into(holder.image_profile);
    isFollowing(user.getId(),holder.btn_follow);

    if (user.getId().equals(firebaseUser.getUid())){
        holder.btn_follow.setVisibility(View.GONE);
    }

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SharedPreferences.Editor editor=mContext.getSharedPreferences("PREFS",Context.MODE_PRIVATE).edit();
            editor.putString("profileid",user.getId());
            editor.apply();

            ((FragmentActivity)mContext).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                    new ProfileFragment()).commit();
        }
    });

    holder.btn_follow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (holder.btn_follow.getText().toString().equals("follow")){
                FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
                        .child("following").child(user.getId()).setValue(true);
                FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
                        .child("followers").child(firebaseUser.getUid()).setValue(true);
            }else {
                FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
                        .child("following").child(user.getId()).removeValue();
                FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
                        .child("followers").child(firebaseUser.getUid()).removeValue();
            }
        }
    });
}
@Override
public int getItemCount() {
    return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
    public TextView username;
    public CircleImageView image_profile;
    public Button btn_follow;
    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        username=itemView.findViewById(R.id.username);
        image_profile=itemView.findViewById(R.id.image_profile);
        btn_follow=itemView.findViewById(R.id.btn_follow);
    }
}
private void isFollowing(String userid,Button button){
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference()
            .child("Follow").child(firebaseUser.getUid()).child("following");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.child(userid).exists()){
                button.setText("following");
            }else {
                button.setText("follow");
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        }
    });
}}

This is the search fragment:

public class SearchFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> mUsers;
EditText search_bar;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_search,container,false);

    recyclerView=view.findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    search_bar=view.findViewById(R.id.search_bar);
    mUsers=new ArrayList<>();
    userAdapter=new UserAdapter(getContext(),mUsers);
    recyclerView.setAdapter(userAdapter);
    readUsers();
    search_bar.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) {
           searchUsers(s.toString().toLowerCase());
        }
        @Override
        public void afterTextChanged(Editable s) {
        }
    });
    return view;
}

private void searchUsers(String s){
    Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("username")
            .startAt(s).endAt(s+"\uf8ff");
    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            mUsers.clear();
            for (DataSnapshot dataSnapshot:snapshot.getChildren()){
                User user = dataSnapshot.getValue(User.class);
                mUsers.add(user);
            }
            userAdapter.notifyDataSetChanged();
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });
}
private void readUsers(){
    DatabaseReference reference=FirebaseDatabase.getInstance().getReference("Users");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (search_bar.getText().toString().equals("")){
                mUsers.clear();
                for (DataSnapshot dataSnapshot:snapshot.getChildren()){
                    User user = dataSnapshot.getValue(User.class);
                    mUsers.add(user);
                }
                userAdapter.notifyDataSetChanged();
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        }
    });
}}

and I'm getting this error when I open search fragment, the app is crashing

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.baranbaldan.disrapev2, PID: 25071
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
    at com.baranbaldan.disrapev2.Adapter.UserAdapter.onBindViewHolder(UserAdapter.java:57)
    at com.baranbaldan.disrapev2.Adapter.UserAdapter.onBindViewHolder(UserAdapter.java:32)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
    at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
    at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
    at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3540)
    at android.view.View.measure(View.java:25466)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.view.View.measure(View.java:25466)
    at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
    at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:146)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6957)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
    at com.android.internal.policy.DecorView.onMeasure(DecorView.java:747)
    at android.view.View.measure(View.java:25466)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3397)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2228)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2486)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
    2021-01-03 12:52:27.402 25071-25071/com.baranbaldan.disrapev2 E/AndroidRuntime:     at 
    android.view.Choreographer.doCallbacks(Choreographer.java:796)
    at android.view.Choreographer.doFrame(Choreographer.java:731)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
    2021-01-03 12:52:27.471 25071-25071/com.baranbaldan.disrapev2 I/Process: Sending signal. PID: 
    25071 SIG: 9

what's wrong I didn't understand. when I'm hiding the readUsers() and searchUsers() app is not crashing but I am not being able to search any user. If you have a better search idea please help me.

2 Answers2

0

Like your error says, you are trying to get a value and compare it to another one but that value is NULL.

I guess this line triggers this exception:

if (user.getId().equals(firebaseUser.getUid())){
    holder.btn_follow.setVisibility(View.GONE);
}

Maybe you are doing something wrong with user IDs but put breakpoint there and check if user.getId() returns any value. You can fix this with something like this:

if (user.getId() != null && user.getId().equals(firebaseUser.getUid())){
    holder.btn_follow.setVisibility(View.GONE);
}

but this is not a complete solution since your users must have IDs. Either that or your firebaseUser is not signed in and because of that, you are getting NULL value on getUid() getter. My advice is to put a breakpoint there and check the list for user IDs or firebaseUser for getUid(). You can use Evaluate this expression in Android Studio after you got on your breakpoint. Just right-click on the marked code sample you want to evaluate and click on Evaluate this expression.

But there is another issue. You are doing some filtering with this but every time you are calling your database and getting other values from the Firebase database. This will not only drain your battery but also sometimes give not that great experience because of Internet latency, low signal, or anything like that. RecylcerView.Adapter has its own Filter that you can use to filter your users using a string keyword. Check it here: https://stackoverflow.com/a/62940041/14759470

SlothCoding
  • 1,546
  • 7
  • 14
0

The error is clear on the logcat. The firebaseUser.getUid() is returning a null object reference because your getCurrentUser() is null which is a result of no user linked. You have to make sure that you have users before fetching userId. Check it again after adding some users manually and rewrite the code using try/catch or if/else so that your app doesn't get crashed if it can't find any user. Ex:

 firebaseUser=FirebaseAuth.getInstance().getCurrentUser();
 if (firebaseUser !=  null){
        if(user.getId().equals(firebaseUser.getUid()){
              holder.btn_follow.setVisibility(View.GONE);
        } else {
              //show error screen or something like that
        }
   }
Roee Ben-Ari
  • 600
  • 3
  • 12