gravition
gravition

Reputation: 113

Android Firebase use geolocation to filter data

I've been working on this problem for a long time and I still haven't think of a solution:Let's say that there are people A,B,C,and D. Each person can publish a profile page containing their pictures and a short-introduction of themselves, and they can allow certain people within their proximities to see these profiles. Let's call this distance a "radius". For example, if a person is a college student, he can allow people on his college campus to see his profile, but not people outside of the campus. Let's say that person A,B,C are each 1,2,8 miles apart from person D, respectively, and A,B, and C set their "radius" to be 2,3,5,respectively, then, person D can see A and B's profile but not C's, because D is within the "radius" of A and B but not C. (2>1,3>2,but 5<8)

I'm thinking about how to achieve this functionality using Firebase and Android. Geofire is a geolocation library for Firebase, but in this case, we're not actively searching for people nearby. In the above example, A,B and C are not searching for D, and D is not searching for A,B and C. Instead, if D is within the "radius" set by certain people, these people's profiles will automatically appear on D's screen. So Geofire's ability to search people within certain distance is not applicable here.

This is what I have so far:I have an array list to display people's names, and below the arrayList I have an editText and a button. A person can enter his name on the EditText, and after clicking the button, add his or her name to the ArrayList. By clicking on the names, other users can see a person's profile.

private ArrayList<String> people = new ArrayList<>();
private DatabaseReference root =   FirebaseDatabase.getInstance().getReference().getRoot();
private Button button1;
private EditText name;
private ListView listview;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 setContentView(R.layout.activity_main);

    super.onCreate(savedInstanceState);
        listview = (ListView) findViewById(R.id.listview);
        name = (EditText) findViewById(R.id.editText);
        button1 = (Button) findViewById(R.id.button1);
        arrayAdapter = new ArrayAdapter<String>(this,     android.R.layout.simple_list_item_1, people);
        listview.setAdapter(arrayAdapter);

   button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Map<String, Object> map = new HashMap<String, Object>();
                map.put(people.getText().toString(), "");
                root.updateChildren(map);

            }
        });

        root.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                Set<String> set = new HashSet<String>();
                Iterator i = dataSnapshot.getChildren().iterator();

                while (i.hasNext()) {
                    set.add(((DataSnapshot) i.next()).getKey());
                }

                people.clear();
                people.addAll(set);

                arrayAdapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

       listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(getApplicationContext(), people.class);
                intent.putExtra("name", ((TextView) view).getText().toString());
                startActivity(intent);
            }
        });
    }

The problem with the above code is that anybody can see anything created by anybody. The functionality to use "radius" to filter the people who can see a person's profile is absent.

I'm thinking about doing this: get a person's geolocation and the "radius" he set and update them to Firebase. Then, when another person's open this app, he retrieve's all the pairs of locations and radius from Firebase, and for each pair, he calculate whether he is within the "radius" of certain people. If he is within the "radius" of certain people, these people's profiles will be displayed on his screen. Is this the correct and most effective way to achieve the functionality? I do not know how to do this with Firebase and Android, specifically, I don't know how to change the above code such that the app will selectively displayed some names from the Arraylist on the screen but not others. The iterator will just go through every member of the Arraylist.

Instead of retrieving all pairs of locations and radius, Is it possible to selectively retrieve certain data from Firebase, (if distance is smaller than radius, retrieve that person's profile from Firebase and display it on the screen)?

Thank you for your help, I know there're a lot of information in my post. I spent all days looking at tutorials about geolocation in Firebase and android and I still haven't find a solution yet.

Upvotes: 2

Views: 620

Answers (1)

random
random

Reputation: 10309

As per GeoFire: How to add extra conditions within the query?, you can only filter by their distance to a given point and cannot add any another condition (like filter by distance set by them).

So its appropriate to get person's geolocation, compare with radius set by other users and filter accordingly. If you're worried about large data being returned to mobile device, you may consider creating a webservice which interacts with this data on the server using GeoFire.js and return filtered data to mobile device.

Upvotes: 1

Related Questions