So I have been trying for a while now to implement a way in which I can update the user if there are no tradesman found or if there are no tradesman within a maximum radius. So the app basically searches for tradesman available within the Firebase and matches with the closest one based on their latitude&longitude. If none are found within 1 mile, it then increments to 2 and so on.
What I have been struggling to implement is a way to say if there is no tradesman available within the firebase or if there are no tradesman available within a certain radius so once it increments to say 10 miles stop and return no tradesman found.
This is the code I have now which searches for the tradesman and increments the radius, but will never stop searching unless I click a button which ends the search, so I need a way to end the search without clicking the button.
private int radius = 1; // 1 radius (mile or km not sure)
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) {
}
});
}
}
@Override
public void onKeyExited(String key) {
}
@Override
public void onKeyMoved(String key, GeoLocation location) {
}
@Override
public void onGeoQueryReady() {
if (!tradesmanFound) {
radius++;
getClosestTradesman();
}
}
@Override
public void onGeoQueryError(DatabaseError error) {
}
});
}
This has been bugging me for a while as it seems like something pretty simple and straightforward in my head, so any help will relive a lot of stress. Thanks
You're really close. When the geoquery is done loading its initial data, it calls onGeoQueryReady
, which you right now have as:
@Override
public void onGeoQueryReady() {
if (!tradesmanFound) {
radius++;
getClosestTradesman();
}
}
So if no tradesmen were found, you start a new query with a larger radius. There two things missing from this:
So in code:
@Override
public void onGeoQueryReady() {
if (!tradesmanFound && radius < 10) {
geoQuery.removeAllListeners();
radius++;
getClosestTradesman();
}
}
I know you already have a call to geoQuery.removeAllListeners()
, but where you currently have it actually doesn't do anything.
I noticed this in your code:
private int radius = 1; // 1 radius (mile or km not sure)
The radius is in kilometers as can be seen in the example query in the docs.