4

In mysql, I was using haversine formula to query nearby object.

Using this formula Formula

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance 
FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

Which

  • 3959: radius of earth in miles
  • 37,-122 : given lat lng
  • 25: within 25 miles

In Firebase, Can I store the users lat lng like what I did in mysql? Create a marker table. id, lat, lng columns and then use the formula to query

Updated

I should ask, what is the way to query nearby using this formula in firebase.

vzhen
  • 11,137
  • 13
  • 56
  • 87

2 Answers2

8

Short answer, not like you want it to.

Firebase essentially has two ways to query for data: by path and by priority. This is more limited than SQL, and there's a very good reason for that — our API is carefully designed to only allow operations we can guarantee to be fast. Firebase is a real-time and scalable backend, and we want to enable you to build great apps that can serve millions of users without compromising on responsiveness.

See, what is firebase and deNormalizing data Also, this SO question is similar.

Response to comment: Firebase will not calculate the sin( radians(X) ) for you. That's a 'slow' operation. So, you would need to store that information into the data when you save it. I'm not 100% certain, but you could store the markers and the also store the longitude/latitude in a separate parent.

Root
    -> Markers
    -> longitude (Use the value as priority) -> MarkerId
    -> latitude (Use the value as priority) -> MarkerId

Then you should be able to use bounding to find the Max and Min longitude and latitude. Use that to query the longitude and latitude paths by priority. If a MarkerId exists in both, you use it.

A quick bit of research found this article on Latitude Longitude Bounding Coordinates

Community
  • 1
  • 1
SH-
  • 1,642
  • 10
  • 13
  • What he's suggesting is that you keep a list of markers prioritized by longitude, and another list prioritized by latitude. You then query both lists, and see where the lists intersect. – Andrew Lee Jun 08 '13 at 04:40
4

Hey I just finished building a real time google map using firebase and GeoFire. GeoFire is really cool and easy to use. It allows you to query using lon lat and radius. It returns a key that you can use to query your firebase db. You set the key, while you create the geoFire object, to be whatever you want. It is usually a ref that you can use to get the object that is associated with that distance.

Here is a link to geoFire: https://github.com/firebase/geofire-js

Here is an example use case:

You have a lon lat, that you got using navigator:

var lon = '123.1232';
var lat = '-123.756';
var user = {
    name: 'test user',
    longitude: lon,
    latitude: lat
}
usersRef.push(user).then(function(response) {
    var key = response.key;
    var coords = [lon, lat];
    geoFire.set(key, coords, function(success){
         console.log('User and geofire object has been created');
    });
})

Now you can query for the user using:

// Set your current lon lat and radius
var geoQuery = geoFire.query({
    center: [latitude, longitude],
    radius: radiusKm
});
geoQuery.on('key_entered', function(key, location, distance) {
    // You can now get the user using the key
    var user = firebaseRefUrl + '/' + key;

    // Here you can create an array of users that you can bind to a   scope in the controller
});

If you are using google maps. I reccomend you use angular-google-maps. Its a really cool google maps directive that takes in an array of markers and circles. So when ever $scope.markers or $scope.circles change in the controller it will automatically be applied to the map without any messy code. They have very good documentation.

Here is a link: http://angular-ui.github.io/angular-google-maps/

user15163
  • 641
  • 1
  • 7
  • 10
  • [You posted this exact same answer to another question](https://stackoverflow.com/a/29310763). Please don't post identical answers to multiple questions. If the questions are duplicates, pick the best one to answer, then flag the other(s) as duplicates. If they are not duplicates, you must [*tailor your answers to each question*](http://meta.stackexchange.com/q/104227/311792). I'll admit I'm not an expert in these technologies, but it doesn't look like this is a direct answer to the question being asked. He's not asking how to query lat & long. (Also, I know this is old, but it was flagged...) – Cody Gray - on strike Aug 08 '17 at 12:24