You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:31:27