Firebase数据获取异常:Android关注功能无法判断用户是否已关注
解决Firebase判断用户关注状态的问题
嘿,我一眼就看到你代码里的两个核心问题,咱们一步步来解决:
问题1:用getKey()判断关注状态完全错误
你之前用mUserDatabase.child(current_uid).child("following").child(user_uid).getKey()获取test,但这个方法不管目标节点是否存在,都会返回你传入的user_uid——因为你明确指定了这个child的键就是user_uid!所以test.equals(user_uid)永远为true,这就是为什么不管有没有关注,都会进入取消关注的逻辑。
问题2:Firebase异步回调的时机错误
你尝试用ValueEventListener的时候,把监听放在了点击事件里,而且直接在监听外面用testing变量判断。但Firebase的回调是异步执行的,你点击按钮后,if (!testing.equals(user_uid))这行代码会先于onDataChange执行,此时testing可能还是初始值,逻辑完全混乱。
正确的实现方案
我们需要在绑定ViewHolder的时候,先异步查询当前用户是否关注了目标用户,设置按钮的初始状态;然后在点击事件里,根据按钮当前的状态执行对应的操作,同时更新Firebase数据和按钮UI。
修正后的onBindViewHolder代码
@Override protected void onBindViewHolder(@NonNull UserViewHolder holder, int position, @NonNull Users model) { final String current_uid = currentUser.getUid(); final String user_uid = getRef(position).getKey(); final Button followBtn = holder.mView.findViewById(R.id.follow_button); followBtn.setTypeface(notes_font); // 1. 先查询当前用户是否关注了目标用户,设置按钮初始状态 mUserDatabase.child(current_uid).child("following").child(user_uid) .addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { boolean isFollowing = dataSnapshot.exists(); if (isFollowing) { // 已关注状态 followBtn.setBackgroundResource(R.drawable.login_button); followBtn.setTextColor(getResources().getColor(R.color.white)); followBtn.setText("Following"); } else { // 未关注状态 followBtn.setBackgroundResource(R.drawable.round_outline); followBtn.setTextColor(getResources().getColor(R.color.app_theme)); followBtn.setText("Follow"); } } @Override public void onCancelled(DatabaseError databaseError) { Toast.makeText(getActivity(), "查询状态失败:" + databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } }); // 2. 按钮点击事件 followBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { final String currentText = followBtn.getText().toString(); if (currentText.equals("Follow")) { // 执行关注操作 mUserDatabase.child(current_uid).child("following").child(user_uid).setValue("true") .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { // 更新对方的粉丝列表 mUserDatabase.child(user_uid).child("follower").child(current_uid).setValue("true"); // 更新按钮状态 followBtn.setBackgroundResource(R.drawable.login_button); followBtn.setTextColor(getResources().getColor(R.color.white)); followBtn.setText("Following"); Toast.makeText(getActivity(), "关注成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getActivity(), "关注失败:" + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } } }); } else if (currentText.equals("Following")) { // 执行取消关注操作 new AlertDialog.Builder(getActivity()) .setTitle("Unfollow?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mUserDatabase.child(current_uid).child("following").child(user_uid).removeValue() .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { // 移除对方的粉丝列表中的当前用户 mUserDatabase.child(user_uid).child("follower").child(current_uid).removeValue(); // 更新按钮状态 followBtn.setBackgroundResource(R.drawable.round_outline); followBtn.setTextColor(getResources().getColor(R.color.app_theme)); followBtn.setText("Follow"); Toast.makeText(getActivity(), "已取消关注", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getActivity(), "取消关注失败:" + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } } }); } }) .setNegativeButton("No", null) .setCancelable(false) .show(); } } }); // 其他ViewHolder绑定逻辑保持不变 holder.setName(model.getName()); holder.setThumbImage(model.getThumbImage()); holder.setStatus(model.getStatus()); holder.mView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent profileIntent = new Intent(getActivity(), All_Profiles.class); profileIntent.putExtra("user_uid", user_uid); startActivity(profileIntent); } }); }
关键改进点
- 用
dataSnapshot.exists()判断关注状态:直接检查目标节点是否存在,这才是正确的判断方式,完全替代了之前错误的getKey()逻辑。 - 使用
addListenerForSingleValueEvent:只查询一次数据,不需要实时监听关注状态(如果需要实时更新,再换成addValueEventListener),减少不必要的资源消耗。 - 基于按钮文本判断操作:点击事件里直接读取按钮当前的文本,避免依赖异步回调的变量,逻辑更可靠。
- 操作成功后立即更新UI:不管是关注还是取消关注,都在Firebase操作成功后同步更新按钮状态,保证UI和数据一致。
这样修改后,就能正确判断用户的关注状态,并且按钮的逻辑也能正常工作啦!
内容的提问来源于stack exchange,提问作者Shadow Suave
相关产品推荐
相关产品推荐

