function fail never called if user declines to share geolocation in firefox
Solution 1:
For Firefox it seems that PERMISSION_DENIED
is raised only if "Never share" is selected; if the dialog is dismissed or "Not now" is selected, effectively nothing happens - even on mozillas geolocation demo if you dismiss the permissions UI nothing happens.
This means that getCurrentPosition
can return either because the user closed the confirmation UI, or because it successfully started it asynchronous request - there doesn't appear to be a way to discriminate between the two.
https://bugzilla.mozilla.org/show_bug.cgi?id=675533
Solution 2:
This is a real pain, and definately not desirable functionality.
The workaround I am using to save the user waiting for ever is to set a timeout to check if the wait spinner is showing after 3 seconds, and if so, hide it and show a manual zip code input:
var latlng;
var waitTime = 3000;
try {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
success(position);
}, showError);
} else {
showError("NOT-SUPPORTED");
}
var t = setTimeout(function () {
if ($("#getZip div.loading").css("display") != "none") {
$("#getZip div.loading").hide();
$("#errorZip").show();
}
}, waitTime);
} catch (evt) {
alert(evt);
}
Solution 3:
As alexleonard pointed out, the only reliable, cross-browser solution I've found for this is to have a setTimeout()
to check the state of your latLng
object/variables, as the timeout
option of getCurrentPosition()
doesn't seem to work reliably. The example below was tested in IE11, Chrome33 and Firefox28.
For a more complete solution that uses a jQuery promise, check out my Gist here: https://gist.github.com/GFoley83/10092929
Example - Hit F12, paste into the console and run
var latLng,
geoOptions = {
enableHighAccuracy: false,
timeout: 5000, // Wait 5 seconds
maximumAge: 300000 // Valid for 5 minutes
};
var userLocationFound = function(position){
latLng = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
window.console.log("User confirmed! Location found: " + latLng.lat + ", " + latLng .lng);
}
var userLocationNotFound = function(){
latLng = {
lat: -41.29247, // fallback lat
lng: 174.7732 // fallback lng
};
window.console.log("Fallback set: ", latLng);
}
window.navigator.geolocation.getCurrentPosition(userLocationFound, userLocationNotFound, geoOptions);
setTimeout(function () {
if(!latLng){
window.console.log("No confirmation from user, using fallback");
userLocationNotFound();
}else{
window.console.log("Location was set");
}
}, geoOptions.timeout + 1000); // Wait extra second