0

I'm trying to make something as follows:

enter image description here

I have an app and I know my location (let's say it is number 4 for the example). I have a defined radius also. I had liked it to show in an adapter below the map all the results that are inside the radius (for example it should show only 1 and 5 - 4 is my location so I don't need it to show).

Now, image that the numbers that im trying to show are users that I have in my Cloud Firestore database. In order to show them on the map, I need to perform a query to check for some condition and then also to check if they are inside the defined radius. If they both have the condition and inside the radius I had like them to be added to the adapter.

I use the following code to implement it:

db.collection("Users").document(document.getData().get( "UserID" ).toString()).collection( "Location" ).get()
                                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                    @Override
                                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                                        if (task.isSuccessful()) {
                                            for (QueryDocumentSnapshot document2 : task.getResult()) {

                                                Object BookLat = document2.getData().get( "Lat" );
                                                Object BookLon = document2.getData().get( "Lon" );

                                                float distance = CalculateDistance(Lat, Lon, BookLat, BookLon);

                                                if (distance <=Radius){
                                                    MapPersonAdapter mapPersonAdapter = new MapPersonAdapter( LocationsActivity.this,document.getData().get( "UserID" ).toString(), distance );
                                                    lvPerson.setAdapter( mapPersonAdapter );
                                                    MapPerson mapPerson = MapPerson.Result(document.getData().get( "UserID" ).toString(), distance);
                                                    mapPersonAdapter.add( mapPerson );
                                                    mapPersonAdapter.notifyDataSetChanged();
                                                }

                                            }
                                        } else {
                                            Log.d("ERROR", "Error getting documents: ", task.getException());
                                        }
                                    }
                                });

Here the problems start.

1) Since I need to check every query for distance, I need to add one-by-one to my adapter. This results that I cant save all results in some array and then insert to adapter (due to void class of async task).

2) I need to make the adapter MapPersonAdapter with variables in it (UserID,distance) since inside the viewHolder of the adapter I need to use:

viewHolder.tvPersonName.setText(person.getPersonName( personID )); 

Which is defined in:

public static String getPersonName(String personID) {
    // PART FOR DISPLAYING PROFILE NAME//
    FirebaseFirestore db = FirebaseFirestore.getInstance();
    CollectionReference username = db.collection( "Users" ).document(personID).collection( "UserData" );
    username.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot document : task.getResult()) {
                    personname = document.getString( "username" );
                }
            } else {
                Log.d(TAG, "Error getting documents: ", task.getException());
            }
        }
    });
    return personname;
}

It causes that I have to initialize the adapter inside the query.

These two problems force me to Initialize the adapter inside the query itself which eventually leads to the main problem that the adapter only shows the last result since it overwrites the views (always returns position 0).

Is there any way to create such an adapter that is called inside a for-loop and yet saves all the results? (Please remember that it is inside async task and it is very complicated to get results outside of the query).

Thank you

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
Ben
  • 1,737
  • 2
  • 30
  • 61

1 Answers1

1

I had liked it to show in an adapter below the map all the results that are inside the radius (for example it should show only 1 and 5 - 4 is my location so I don't need it to show).

There is currently no way you can query a Cloud Firestore database using geolocation. Firestore does not support GeoPoint queries. The only way you can solve this is to use geohashes. There is also a very useful video where Frank van Puffelen explains in details the same topic.

Beside that, if you are using Android, there is also a library named GeoFirestore library for Android that can help you get nearby location within a specific radius.

Furthermore, Firebase APIs are asynchronous so you cannot return the data that you are getting from the database as a reusult of a method. A quick solve for this problem would be to use the value of the personname only inside the onComplete() method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193