AngularJS Firebase Ionic Geolocation


#1

Hi folks,

Im building a hobby project that helps to filter a ion-list or ng-repeat list (If without ionic) by:

  1. geolocation of the post creator (upon submitting) in relation to,
  2. reader’s current location.

I dont require a display of the physical map which Google API requires as part of their API rules. Some of the other location service (like Cordova plugin) is better as it captures actual location instead of IP but somehow isnt accurate. I dont need it to be super precise but it has to be updated timely if a user changes location.

Does anyone have any suggestions or solutions? Or did I do something wrong?

Any rough codes to explain the concept is appreciated.

Many thanks!

I refer to some links here.


http://blog.dynamicprogrammer.com/2014/05/05/recording-geolocation-data-PhoneGap-part-3.html

Some options I looked at:


http://ngmodules.org/modules/angular-cordova-geolocation
https://developers.google.com/maps/documentation/javascript/examples/map-geolocation


#2

Hi mthh,

I need a bit more of an explanation - from what I understand you want to use Geolocation without a map?

I do this in my app - basically I have a Map view and a List View. Each one has a service call that takes in Longitude and Latitude and shows the poker games within X miles of this point (this is just a SQL Server query.

This is how my List page looks: (Note, this code is still beta and I have a lot of tidying up and abstracting to do still)

"use strict";

(function () {
    angular.module('pokerGameFinder.gamesListCtrl', [])    

        .controller('GamesListCtrl', function($rootScope, $log, $scope, $ionicPlatform, gameadrepository, findmylocation, searchData, appConfig, AnalyticsTracker, toastr, LoaderService) {
            $log.info("GamesListCtrl", searchData.getLocation())
            
            $ionicPlatform.ready(function() {
                checkLocation();
            });
            
            //abstract this into a service
            $scope.findAddress = function (address) {
                var geocoder = new google.maps.Geocoder();

                geocoder.geocode({ 'address': address}, function(results, status) {
                    $log.debug(address, results, status);
                    if (status === google.maps.GeocoderStatus.OK) {
                        var location = { searchTerm: address, latitude: results[0].geometry.location.lat(), longitude: results[0].geometry.location.lng(), milesRadius:25 };      
                        searchData.setLocation(location); 
                        $scope.addressText = searchData.getLocation().searchTerm;
                        loadGamesForLocation(searchData.getLocation());
                    } else {
                        AnalyticsTracker.logError('Could not geocode this address: ' + status);
                        toastr.show('Address not found - please try again');
                    }
                });
                return;
            };
            
            $scope.findMyLocation = function() {
                findmylocation.getCurrentLocation().then(function(location) {
                    searchData.setLocation(location); 
                    $scope.gameAds = gameadrepository.getGamesForLocation(location);
                    $scope.addressText = searchData.getLocation().searchTerm;
                }, function() {
                    //don't know why I have to put this here but it would not hide on iOS if not (does not fire in the error handler on the Service for some reason)
                    LoaderService.hide();
                });
            }
         
            function checkLocation() {
                //center the map on the user's location if it has not been set yet
                //var location = $rootScope.searchLocation;
                if (searchData.getLocation() === null) {
                    findmylocation.getCurrentLocation()
                        .then(function(location) {
                            searchData.setLocation(location); 
                            $scope.addressText = searchData.getLocation().searchTerm;
                            loadGamesForLocation(searchData.getLocation());
                        }, function(error) {
                            //could not get current location or was denied - so do no nothing and the user can type a location - enter the default location in case they go to the List page without searching
                            searchData.setLocation(appConfig.startingLocation);
                            $scope.addressText = searchData.getLocation().searchTerm;
                            loadGamesForLocation(searchData.getLocation());
                        });
                } else {
                    loadGamesForLocation(searchData.getLocation());
                    $scope.addressText = searchData.getLocation().searchTerm;
                }
            }
            
            function loadGamesForLocation(location) {
                //load the game for this location
                gameadrepository.getGamesForLocation(location)
                    .$promise.then(function(gameAds) {
                        $scope.gameAds = gameAds;
                    });   
            }
        })
}());

and here is the FinMyLocation Service:

//http://ngcordova.com/docs/#Geolocation
"use strict";

(function () {
    angular.module('pokerGameFinder')
        .factory('findmylocation', function($log, $cordovaGeolocation, $q, $ionicPlatform, LoaderService, AnalyticsTracker, toastr) {
            return {
                getCurrentLocation: getCurrentLocation
            };
                
            function getCurrentLocation(showErrors) {
                //http://andyshora.com/promises-angularjs-explained-as-cartoon.html
                //default to show errors if it is not passed in
                showErrors = typeof showErrors !== 'undefined' ? showErrors : true;
               
                LoaderService.show();
                var deferred = $q.defer();
                
                //does this need to be wrapped in a try catch in case it is not rwady?!?! try()
                $cordovaGeolocation.getCurrentPosition()
                    .then(function (position) {
                        var addressText = "Current Location";
                        var currentLocation = null;
                        
                        //get the address for these coords
                        //http://www.raymondcamden.com/2013/3/5/Simple-Reverse-Geocoding-Example
                        //http://www.jasonwatmore.com/post/2014/02/15/AngularJS-Reverse-Geocoding-Directive.aspx
                        var geocoder = new google.maps.Geocoder();
                        var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                        geocoder.geocode({ 'latLng': latlng }, function (results, status) {
                            if (status === google.maps.GeocoderStatus.OK) {
                                if (results[1]) {
                                    addressText = results[1].formatted_address;
                                } else {
                                    //don't do anything
                                    if (showErrors) {
                                        toastr.show('Address not found - please try again');
                                    }
                                }
                            } else {
                                if (showErrors) {
                                    $log.debug('Address Geocoder failed due to: ' + status);
                                    toastr.show('Address not found - please try again');
                                }
                            }
                            
                            currentLocation = { searchTerm: addressText, latitude: position.coords.latitude, longitude: position.coords.longitude, milesRadius: 25 }
                            $log.debug('Found current location', currentLocation);
                            
                            AnalyticsTracker.event('findmylocation.getCurrentLocation');
                            LoaderService.hide();
                            deferred.resolve(currentLocation);
                        });
                    }, function(error) {
                        $log.debug('getCurrentLocation', error);
                        
                        LoaderService.hide();
                        
                        AnalyticsTracker.logError(error);
                        
                        if (showErrors) {
                            toastr.show('Could not find your location - is your GPS on?');
                        }

                        deferred.reject(error);
                    });
                return deferred.promise;
            }
        });
}());

#3

Yeah. I am in the same boat with firebase.


#4

Hi,

I had some problems with getting an accurate position myself. I posted a question about it (didn’t got much response :slight_smile: )
here is the link Geolocation and accuracy
In short getCurrentPosition isn’t always accurate because it returns a result to soon.
The guy from the repo wrote a function getAccuratePosition which uses watchPosition to get a better fix.

If you like to know if a user has changed position watchPosition is the way to go. It creates a watch which updates if the user moves.

Can’t give you proper code because I’m still wrestling with it myself :slight_smile:
The getAccuratePosition works though tested it with 20m accuraccy.


#5

The reason why I did post codes is because I understood very little of them.
Hence my question as posted.

However I took a look at the guy who replied to you, his format is somewhat different from what I had.

Mines similar to this one.

Generally you either use the $rootScope style or you use Broadcast as the example below.

And yes I use watchPosition instead.

Alternative;y if you use Google maps…
The Ionic folks had a reply here: