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

Firebase/GeoQuery最大半径判断逻辑实现求助

解决方案:实现搜索半径上限自动终止并提示用户

我来帮你搞定这个自动终止搜索的问题!你当前代码的核心问题在于,每次搜索完没找到技工,就直接扩大半径继续递归搜索,但完全没判断是否已经达到你设定的max_radius上限,所以才会无限循环下去。

只需要在递归前加个判断:如果当前半径已经到顶了,就停止搜索并给用户反馈;否则继续扩大范围找。下面是修改后的完整代码,关键改动我都标了注释:

private int radius = 1; // 初始搜索半径(英里)
private int max_radius = 15; // 最大搜索半径
private Boolean tradesmanFound = false;
private String tradesmanFoundID;
GeoQuery geoQuery;

private void getClosestTradesman() {
    DatabaseReference tradesmanLocation = FirebaseDatabase.getInstance().getReference().child("TradesmanAvailable");
    GeoFire geoFire = new GeoFire(tradesmanLocation);
    geoQuery = geoFire.queryAtLocation(new GeoLocation(customerLocation.latitude, customerLocation.longitude), radius);
    geoQuery.removeAllListeners();
    geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
        @Override
        public void onKeyEntered(String key, GeoLocation location) {
            if (!tradesmanFound && requestBol) {
                DatabaseReference customerDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child("Tradesman").child(key);
                customerDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (dataSnapshot.exists() && dataSnapshot.getChildrenCount() > 0) {
                            Map<String, Object> tradesmanMap = (Map<String, Object>) dataSnapshot.getValue();
                            if (tradesmanFound) {
                                return;
                            }
                            if (tradesmanMap.get("Trade").equals(tradeType)) {
                                tradesmanFound = true;
                                tradesmanFoundID = dataSnapshot.getKey();
                                DatabaseReference tradesmanRef = FirebaseDatabase.getInstance().getReference().child("Users").child("Tradesman").child(tradesmanFoundID).child("CustomerRequest");
                                String customerID = FirebaseAuth.getInstance().getCurrentUser().getUid();
                                HashMap map = new HashMap();
                                map.put("CustomerRequestID", customerID);
                                tradesmanRef.updateChildren(map);
                                getTradesmanLocation();
                                getTradesmanInfo();
                                isRequestFinished();
                                requestTradesmanBtn.setText("Looking for Tradesman's Location...");
                            }
                        }
                    }
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        // 加个错误日志,方便排查问题
                        Log.e("TradesmanSearch", "数据库查询失败: " + databaseError.getMessage());
                    }
                });
            }
        }

        @Override
        public void onKeyExited(String key) {}

        @Override
        public void onKeyMoved(String key, GeoLocation location) {}

        @Override
        public void onGeoQueryReady() {
            if (!tradesmanFound) {
                // 关键改动:判断是否达到最大搜索半径
                if (radius >= max_radius) {
                    // 终止搜索,给用户提示
                    tradesmanFound = true; // 标记为已完成,防止重复触发
                    requestTradesmanBtn.setText("未找到" + max_radius + "英里范围内的可用技工");
                    Toast.makeText(getApplicationContext(), "抱歉,当前区域没有可用的匹配技工", Toast.LENGTH_LONG).show();
                    return;
                }
                // 没到上限就扩大半径继续搜
                radius++;
                getClosestTradesman();
            }
        }

        @Override
        public void onGeoQueryError(DatabaseError error) {
            // 搜索出错时也要给用户反馈
            Log.e("TradesmanSearch", "Geo查询失败: " + error.getMessage());
            Toast.makeText(getApplicationContext(), "搜索失败,请稍后重试", Toast.LENGTH_LONG).show();
        }
    });
}

额外优化建议:

每次用户发起新的搜索请求时,记得重置搜索状态,避免上次的状态影响新搜索,比如在请求按钮的点击事件里加上:

requestTradesmanBtn.setOnClickListener(v -> {
    radius = 1;
    tradesmanFound = false;
    tradesmanFoundID = null;
    requestBol = true;
    requestTradesmanBtn.setText("正在寻找技工...");
    getClosestTradesman();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:07:42