GeoFirestore has at least two methods for returning the documents in Firestore.
getAtLocation()
and geoFirestore.queryAtLocation(new GeoPoint(lati, longi), radi).addGeoQueryDataEventListener()
According to the documentation, getAtLocation()
will return to the SingleGeoQueryDataEventCallback
a list of all the documents presents in the area and an exception if something goes wrong.
Below is how I am doing the queries:
if (!lat.getText().toString().isEmpty()) {
lati = Double.parseDouble(lat.getText().toString());
longi = Double.parseDouble(lon.getText().toString());
}
double radi = Double.parseDouble(rad.getText().toString());
Log.i(TAG, "onClick: radius is "+radi);
geoFirestore.getAtLocation(new GeoPoint(lati, longi), radi, new GeoFirestore.SingleGeoQueryDataEventCallback() {
@Override
public void onComplete(@Nullable List<? extends DocumentSnapshot> list, @Nullable Exception e) {
//Log.i(TAG, "GeoFirestore: onComplete");
if (e != null) {
Log.i(TAG, "GeoFirestore: onComplete: error");
return;
} else {
Log.i(TAG, "GeoFirestore: onComplete: list.size() is "+list.size());
for (DocumentSnapshot documentSnapshot : list) {
Log.i(TAG, "GeoFirestore: onComplete: documentSnapshot is "+documentSnapshot);
}
}
}
});
geoQuery = geoFirestore.queryAtLocation(new GeoPoint(lati, longi), radi);
geoQuery.addGeoQueryDataEventListener(new GeoQueryDataEventListener() {
@Override
public void onDocumentEntered(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentEntered: addGeoQueryDataEventListener - documentSnapshot is "+documentSnapshot);
}
@Override
public void onDocumentExited(@NotNull DocumentSnapshot documentSnapshot) {
Log.i(TAG, "onDocumentExited: addGeoQueryDataEventListener - documentSnapshot is "+documentSnapshot);
}
@Override
public void onDocumentMoved(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentMoved: addGeoQueryDataEventListener - documentSnapshot is "+documentSnapshot);
}
@Override
public void onDocumentChanged(@NotNull DocumentSnapshot documentSnapshot, @NotNull GeoPoint geoPoint) {
Log.i(TAG, "onDocumentChanged: addGeoQueryDataEventListener - documentSnapshot is "+documentSnapshot);
}
@Override
public void onGeoQueryReady() {
Log.i(TAG, "onGeoQueryReady: addGeoQueryDataEventListener");
}
@Override
public void onGeoQueryError(@NotNull Exception e) {
Log.i(TAG, "onGeoQueryError: addGeoQueryDataEventListener");
}
});
And below is the result of both queries:
debinf FirebaseAct: onClick: radius is 10.0
debinf FirebaseAct: onDocumentEntered: addGeoQueryDataEventListener - documentSnapshot is DocumentSnapshot{key=Stores/P7FfBlnChxqkjABsONSo, metadata=SnapshotMetadata{hasPendingWrites=false, isFromCache=false}, doc=Document{key=Stores/P7FfBlnChxqkjABsONSo, data=ArraySortedMap{(address=>av. fernandes lima, s/n - farol), (city=>maceio), (g=>7nq96cb3e3), (id=>222222222), (image=>http://walmart), (l=>GeoPoint { latitude=-9.614147, longitude=-35.738036 }), (name=>walmart), (opening=>ArraySortedMap{(fri=>07:00-23:59), (mon=>07:00-23:59), (sat=>07:00-22:00), (sun=>07:00-18:00), (thu=>07:00-23:59), (tue=>07:00-23:59), (wed=>07:00-23:59)};), (phone=>), (state=>alagoas)};, version=SnapshotVersion(seconds=1574434563, nanos=920733000), documentState=SYNCED}}
debinf FirebaseAct: onDocumentEntered: addGeoQueryDataEventListener - documentSnapshot is DocumentSnapshot{key=Stores/iKIZ9n54jpnThvNx0Prw, metadata=SnapshotMetadata{hasPendingWrites=false, isFromCache=false}, doc=Document{key=Stores/iKIZ9n54jpnThvNx0Prw, data=ArraySortedMap{(address=>avenida maceio, s/n - Tabuleiro), (city=>maceio), (g=>7nq96p934s), (id=>333333333), (image=>http://gbarbosa), (l=>GeoPoint { latitude=-9.58262891, longitude=-35.76965511 }), (name=>GBarbosa), (opening=>ArraySortedMap{(fri=>07:00-21:00), (mon=>07:00-21:00), (sat=>07:00-21:00), (sun=>07:00-18:00), (thu=>07:00-21:00), (tue=>07:00-21:00), (wed=>07:00-21:00)};), (phone=>), (state=>alagoas)};, version=SnapshotVersion(seconds=1574445438, nanos=550840000), documentState=SYNCED}}
debinf FirebaseAct: onDocumentEntered: addGeoQueryDataEventListener - documentSnapshot is DocumentSnapshot{key=Stores/8HU4UdSLNEaCg5eqeZbq, metadata=SnapshotMetadata{hasPendingWrites=false, isFromCache=false}, doc=Document{key=Stores/8HU4UdSLNEaCg5eqeZbq, data=ArraySortedMap{(address=>avenida vereador dario marsiglia, s/n - cleto marques luz), (city=>maceio), (g=>7nq9d32m26), (id=>123456789), (image=>http://tim), (l=>GeoPoint { latitude=-9.57229704, longitude=-35.76013863 }), (name=>Lider), (opening=>ArraySortedMap{(fri=>07:00-23:59), (mon=>07:00-23:59), (sat=>07:00-23:59), (sun=>07:00-23:59), (thu=>07:00-23:59), (tue=>07:00-23:59), (wed=>07:00-23:59)};), (phone=>ddd xxxx-yyyy), (state=>alagoas)};, version=SnapshotVersion(seconds=1574444945, nanos=558590000), documentState=SYNCED}}
debinf FirebaseAct: onGeoQueryReady: addGeoQueryDataEventListener
debinf FirebaseAct: GeoFirestore: onComplete: list.size() is 1
debinf FirebaseAct: GeoFirestore: onComplete: documentSnapshot is DocumentSnapshot{key=Stores/P7FfBlnChxqkjABsONSo, metadata=SnapshotMetadata{hasPendingWrites=false, isFromCache=false}, doc=Document{key=Stores/P7FfBlnChxqkjABsONSo, data=ArraySortedMap{(address=>av. fernandes lima, s/n - farol), (city=>maceio), (g=>7nq96cb3e3), (id=>222222222), (image=>http://walmart), (l=>GeoPoint { latitude=-9.614147, longitude=-35.738036 }), (name=>walmart), (opening=>ArraySortedMap{(fri=>07:00-23:59), (mon=>07:00-23:59), (sat=>07:00-22:00), (sun=>07:00-18:00), (thu=>07:00-23:59), (tue=>07:00-23:59), (wed=>07:00-23:59)};), (phone=>), (state=>alagoas)};, version=SnapshotVersion(seconds=1574434563, nanos=920733000), documentState=SYNCED}}
How to make getAtLocation()
return a list of documents just like addGeoQueryDataEventListener()
?
As of version v1.5.0, there is a discrepancy between the code and the documentation. The documentation states that queryAtLocation
uses kilometers:
// creates a new query around [37.7832, -122.4056] with a radius of 0.6 kilometers
val geoQuery = geoFirestore.queryAtLocation(GeoPoint(37.7832, -122.4056), 0.6)
However, the code converts from meters to latitude:
fun distanceToLatitudeDegrees(distance: Double) = distance / Constants.METERS_PER_DEGREE_LATITUDE
There is an open issue on Github.
Passing meters to the queryAtLocation should solve the problem.