首页 > 解决方案 > Android Studio-我正在尝试从 firebase 数据库中搜索用户,但出现错误

问题描述

我试图做到这一点:

我的用户模型:

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;
}}

这是用户适配器:

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) {
        }
    });
}}

这是搜索片段:

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) {
        }
    });
}}

当我打开搜索片段时出现此错误,应用程序崩溃

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

我不明白怎么了。当我隐藏应用程序时readUsers()searchUsers()应用程序没有崩溃,但我无法搜索任何用户。如果您有更好的搜索想法,请帮助我。

标签: javaandroidfirebase

解决方案


logcat 上的错误很明显。firebaseUser.getUid()正在返回一个空对象引用,因为您是getCurrentUser()空的,这是没有用户链接的结果。您必须确保在获取userId. 手动添加一些用户后再次检查它并使用 try/catch 或 if/else 重写代码,以便您的应用在找不到任何用户时不会崩溃。前任:

 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
        }
   }

推荐阅读