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

ArrayList逻辑错误:符合条件的数据未正确存入列表(Firebase代码)

问题排查与修复方案

问题根源分析

  1. 列表被重复覆盖:在geofenceDB的子节点循环中,每次迭代都给searchDB添加新的ValueEventListener,且每次onDataChange都会重新创建tutorArrayList。这导致最后一次循环的结果直接覆盖之前所有符合条件的数据——比如半径设为10时,最后遍历到距离290的节点,此时条件不满足,数组为空,最终显示空数组。
  2. 逻辑匹配倒置:当前代码错误地将Geo-fence中每个用户的位置当作tutor的位置,再去Users中遍历所有用户判断类型。正确逻辑应该是:先从Users筛选出tutor类型的用户,再到Geo-fence获取该tutor的真实位置,计算与当前用户的距离是否在半径范围内。
  3. 资源浪费:重复添加监听会多次读取searchDB数据,浪费带宽且引发不必要的UI刷新。

修正后的代码

searchDB = FirebaseDatabase.getInstance().getReference("Users");
geofenceDB = FirebaseDatabase.getInstance().getReference("Geo-fence");

searchList.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
searchList.setLayoutManager(layoutManager);

String userID = FirebaseAuth.getInstance().getUid();
// 仅获取一次当前用户的位置与半径
geofenceDB.child(userID).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot userSnapshot) {
        if (!userSnapshot.exists()) return;
        
        final double userLat = userSnapshot.child("Latitude").getValue(Double.class);
        final double userLng = userSnapshot.child("Longitude").getValue(Double.class);
        final double userRadius = userSnapshot.child("Radius").getValue(Double.class);

        // 获取所有用户数据,筛选tutor类型
        searchDB.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot usersSnapshot) {
                tutorArrayList = new ArrayList<>();
                for (DataSnapshot userNode : usersSnapshot.getChildren()) {
                    User tutor = userNode.getValue(User.class);
                    if (tutor == null) continue;
                    
                    String typeData = tutor.getType().toLowerCase(Locale.ROOT);
                    if (!"tutor".equals(typeData)) continue;

                    // 获取当前tutor的位置数据
                    String tutorID = userNode.getKey();
                    geofenceDB.child(tutorID).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot tutorLocSnapshot) {
                            if (!tutorLocSnapshot.exists()) return;
                            
                            double tutorLat = tutorLocSnapshot.child("Latitude").getValue(Double.class);
                            double tutorLng = tutorLocSnapshot.child("Longitude").getValue(Double.class);
                            
                            // 判断距离是否符合要求,符合则加入列表
                            if (calculateDistanceInKilometer(userLat, userLng, tutorLat, tutorLng) <= userRadius) {
                                tutorArrayList.add(tutor);
                            }
                            updateRecyclerView();
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError error) {}
                    });
                }
                // 处理无符合条件数据的情况
                updateRecyclerView();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {}
        });
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {}
});

// 统一UI更新逻辑,避免重复代码
private void updateRecyclerView() {
    if (adapter == null) {
        adapter = new SearchAdapter(getActivity(), tutorArrayList);
        searchList.setAdapter(adapter);
    } else {
        adapter.notifyDataSetChanged();
    }
    
    if (tutorArrayList.isEmpty()) {
        searchList.setVisibility(View.GONE);
        empty.setVisibility(View.VISIBLE);
    } else {
        searchList.setVisibility(View.VISIBLE);
        empty.setVisibility(View.GONE);
    }
}

关键优化点

  • 使用addListenerForSingleValueEvent替代addValueEventListener,避免持续监听数据变化,减少无效请求与UI刷新。
  • 调整逻辑顺序:先筛选tutor类型用户,再匹配其位置与距离条件,确保每个符合要求的tutor都能被正确加入列表。
  • 提取独立的updateRecyclerView方法,统一处理UI更新逻辑,避免代码冗余。
  • 增加空值判断,防止因数据缺失引发的异常。

内容的提问来源于stack exchange,提问作者Izz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:24:44