navigator.geolocation:: Location request timed out issue React Native - react-native

I am building a React Native app and trying to get my current geocodes using navigator.geolocation It shows me an error of Location request Time out. Basically I am building a tracking app and I need to configure the exact location latitude longitude. To start tracking there is one button and click of this tracking would be start and it should be the initial point for tracking. I am using default react native geolocation API, Link https://facebook.github.io/react-native/docs/geolocation
Function to get my current location::
getLocation() {
navigator.geolocation.getCurrentPosition(response => {
console.log(response);
if (response && response.coords) {
this.saveLogs(response.coords);
}
},
(error) => {
this.onGeolocationErrorOccurCallback(error);
},
GeolocationOptions
)
}
It shows me an Error::
{"TIMEOUT":3,"POSITION_UNAVAILABLE":2,"PERMISSION_DENIED":1,"message":"Location
request timed out", "code":3}
I have added permission for Android device, and also checking by set enableHighAccuracy value to false. But it's not working for me. And I need to set enableHighAccuracy to true because I want exact geocodes to track someone. Please suggest why Location request timed out is occurring here??

UPDATE: 2021 June 12,
This approach works for me in Android Emulator. "react-native": "0.64.1" and Android API 30
import Geolocation from "#react-native-community/geolocation";
const getGeoLocaation = () => {
const config = {
enableHighAccuracy: true,
timeout: 2000,
maximumAge: 3600000,
};
Geolocation.getCurrentPosition(
info => console.log("INFO", info),
error => console.log("ERROR", error),
config,
);
};

The code below worked for me:
componentDidMount(){
if(Platform.OS === 'android'){
this.requestLocationPermission()
}else{
this._getCurrentLocation()
}
}
async requestLocationPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'Location Permission',
'message': 'MyMapApp needs access to your location'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this._getCurrentLocation()
console.log("Location permission granted")
} else {
console.log("Location permission denied")
}
} catch (err) {
console.warn(err)
}
}
_getCurrentLocation = () =>{
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
})
},
(error) => {
this.setState({ error: error.message })},
{ enableHighAccuracy: true, timeout: 200000, maximumAge: 1000 },
);
}
Permission in Manifest file:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Just make sure your location is enabled.

Try to use:
enableHighAccuracy: false
Worked for me!
const getUserCurrentLocation = () => {
let latitude, longitude
Geolocation.getCurrentPosition(
info => {
const { coords } = info
latitude = coords.latitude
longitude = coords.longitude
setLat(latitude)
setLng(longitude)
getUserCurrentAddress(latitude, longitude)
},
error => console.log(error),
{
enableHighAccuracy: false,
timeout: 2000,
maximumAge: 3600000
}
)
}

I add the same issue ({"TIMEOUT":3,"POSITION_UNAVAILABLE":2,"PERMISSION_DENIED":1,"message":"Location request timed out", "code":3})
After reading the following documents,
https://developer.android.com/training/location/permissions#java
https://github.com/react-native-geolocation/react-native-geolocation/blob/master/example/GeolocationExample.js'
I understood that, I need to add:
in the manifest AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And increment the timeout as follow
{
enableHighAccuracy: false,
timeout: 2000,
maximumAge: 3600000
}
-- code snipet
Geolocation.getCurrentPosition(
position => {
const initialPosition = JSON.stringify(position);
console.log(initialPosition)
// this.setState({initialPosition});
},
error => console.log('Error', JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000},
);

Related

app crash when using Geolocation in React-Native

I am using react-native-geolocation-service, I have such function to get coords. And then by Geocoder api get the city by coords. I check the permission status by react-native-permissions:
export const getCity = async (dispatch: Dispatch<any>) => {
const granted = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
if (granted === RESULTS.DENIED) {
await PermissionsAndroid.request(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION, {
buttonNegative: undefined,
buttonNeutral: undefined,
buttonPositive: '',
title: 'Access',
message: 'give access',
});
}
if (granted === RESULTS.GRANTED || granted === RESULTS.LIMITED) {
Geolocation.getCurrentPosition(
position => {
const coords: Coords = {
Longitude: position.coords.longitude,
Latitude: position.coords.latitude,
};
dispatch(thunks.geocoder.getGeocoderInfo(coords));
Alert.alert('coords', `${coords.Latitude}, ${coords.Longitude}`);
},
error => Alert.alert('Error', `Error ${error.message}`),
{
enableHighAccuracy: false,
timeout: 20000,
maximumAge: 3600000,
},
);
}
};
So, when my applications starts, I grant the permission to it, and then it just closes. Also I added access into AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>. And then I call this function inside my component using UseEffect()
I solved my problem. I rewrite my code form question as follows:
type Coords = {
coords: {
accuracy?: number | null;
altitude?: number | null;
altitudeAccuracy?: number | null;
heading?: number | null;
latitude?: number | null;
longitude?: number | null;
speed?: number | null;
};
mocked?: boolean;
provider?: string;
timestamp?: number | null;
};
export const getCity = async (dispatch: Dispatch<any>) => {
const granted = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
let geoOptions = {
enableHighAccuracy: true,
timeOut: 20000,
maximumAge: 60 * 60 * 24,
};
const geoSuccess = (position: Coords) => {
const coords = {
Latitude: position.coords.latitude,
Longitude: position.coords.longitude,
};
dispatch(thunks.geocoder.getGeocoderInfo(coords));
};
const geoFailure = (err: any) => {
console.log({error: err.message});
};
if (granted === RESULTS.DENIED) {
const data = await PermissionsAndroid.request(
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
{
buttonNegative: undefined,
buttonNeutral: undefined,
buttonPositive: '',
title: 'Access',
message: 'give access',
},
);
}
if (granted === RESULTS.GRANTED || granted === RESULTS.LIMITED) {
Geolocation.getCurrentPosition(geoSuccess, geoFailure, geoOptions);
}
};
So it solved my problem. App now doesn't crush.
This issue can be solved by upgrading your react native to 0.70.1, i just solved that problem and now the gelocaiton service is working fine in both debug and release apk.
and dont forget to add use permission in androidmanifest.xml

Why location permission pop up not showing in React Native?

I want to implement get current location in react native. I put permission to activate location if location is not activate in phone before calling geolocation API but pop up not showing and this PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,{ title: 'Location Access Required', message: 'This App needs to Access your location'},); always return "granted" when request permission using PermissionAndroid module.
this is my code
import { PermissionsAndroid } from 'react-native';
import Geolocation from '#react-native-community/geolocation';
...
componentDidMount(){
const requestLocationPermission = async () => {
let geoOptions = {
enableHighAccuracy: true,
timeout:20000,
maximumAge: 60*60*24
}
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Access Required',
message: 'This App needs to Access your location',
},
);
console.warn(granted);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
Geolocation.getCurrentPosition(this.geoLocationSuccess,this.geoLocationFailure,geoOptions);
}
} catch (err) {
console.warn(err);
}
};
requestLocationPermission();
}
is my implementation is wrong ? because i want to show pop up when location service is not enable to let user enable it
This may be of little help, first make sure no library location other than react-native-geolocation-service. then if there is no use react hook. you might try this method below.
hasLocationPermission = async () => {
const hasPermission = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
if (hasPermission === PermissionsAndroid.RESULTS.GRANTED) {
console.log('lagi req permission');
return true;
}
const status = await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
);
if (status) {
console.log('permission diberikan');
return true;
}
if (status === PermissionsAndroid.RESULTS.DENIED) {
ToastAndroid.show(
'Location permission denied by user.',
ToastAndroid.LONG,
);
} else if (status === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
ToastAndroid.show(
'Location permission revoked by user.',
ToastAndroid.LONG,
);
}
return false;
};
async componentDidMount() {
if (await this.hasLocationPermission()) {
Geolocation.getCurrentPosition(
position => {
console.log('posisi ditemukan',position.coords.latitude, position.coords.longitude);
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
this.goToRegion(position.coords.latitude, position.coords.longitude);
},
error => {
Alert.alert(
'Oopss!',
error.message,
[
{
text: 'OK',
onPress: () => console.log('Cancel Pressed'),
},
],
);
console.log(error.message);
this.setState({error: error.message});
},
{
accuracy: {
android: 'high',
ios: 'best',
},
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 10000,
distanceFilter: 0,
forceRequestLocation: true,
forceLocationManager: false,
showLocationDialog: true,
},
);
}
}

React native geolocation service not working for iOS

I am trying to get device current position in react native. I am using below library for get the location:
react-native-geolocation-service
My code:
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Device current location permission',
message:
'Allow app to get your current location',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.getCurrentLocation();
} else {
console.log('Location permission denied');
}
} catch (err) {
console.warn(err);
}
}
getCurrentLocation(){
Geolocation.requestAuthorization();
Geolocation.getCurrentPosition(
(position) => {
alert(position.coords.latitude);
this.socket.emit('position', {
data: position,
id: this.id,
});
},
(error) => {
alert("map error: "+error.message);
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
}
Android is working fine and getting the correct location but for IOS it's not working Also, it's not asking for allow location persmission. I am getting below error:
PERMISSION_DENIED: 1
POSITION_UNAVAILABLE: 2
TIMEOUT: 3
code: 3
message: "Unable to fetch location within 15.0s."
This is my info.plist:
<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) would like to access your location.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>$(PRODUCT_NAME) would like to access your location.</string>
This is background modes from xcode
I have used the react-native-geolocation-service for getting user current location here is my code
App.js:
import Geolocation from 'react-native-geolocation-service';
async componentDidMount() {
if(Platform.OS === 'ios'){
this.getCurrentLocation();
}else{
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Device current location permission',
message:
'Allow app to get your current location',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.getCurrentLocation();
} else {
console.log('Location permission denied');
}
} catch (err) {
console.warn(err);
}
}
}
getCurrentLocation(){
Geolocation.requestAuthorization();
Geolocation.getCurrentPosition(
(position) => {
console.log(position);
},
(error) => {
console.log("map error: ",error);
console.log(error.code, error.message);
},
{ enableHighAccuracy: false, timeout: 15000, maximumAge: 10000 }
);
}
MapScreen.js
import Geolocation from 'react-native-geolocation-service';
componentDidMount() {
this.updateCurrentPosiiton();
}
updateCurrentPosiiton () {
Geolocation.getCurrentPosition(
(position) => {
let d_lat = position.coords.latitude;
let d_lng = position.coords.longitude;
this.setState({
current_lat: position.coords.latitude,
current_lng: position.coords.longitude
})
// console.log('aayaaa');
this.props.updateGps(d_lat,d_lng);
this.getTrackData(d_lat,d_lng);
},
(error) => {
console.log("map error: ",error);
console.log(error.code, error.message);
},
{ enableHighAccuracy: false, timeout: 15000, maximumAge: 10000 }
);
}
Please let me know if any issue.
I have solved this issue by this
async requestPermission() {
try {
const granted = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
]).then((result) => {
console.log(result);
if (
result['android.permission.ACCESS_COARSE_LOCATION'] &&
result['android.permission.ACCESS_FINE_LOCATION'] === 'granted'
) {
this.getLocation();
this.setState({
permissionsGranted: true,
});
}
});
} catch (err) {
console.warn(err);
}
}
getLocation() {
Geolocation.getCurrentPosition(
(position) => {
console.log(position);
},
(error) => {
// See error code charts below.
console.log(error.code, error.message);
},
{enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
);
}
componentDidMount() {
if (Platform.OS === 'ios') {
Geolocation.requestAuthorization('always').then((res) => {
console.log(res);
});
}
if (Platform.OS === 'android') {
this.requestPermission();
} else {
this.getLocation();
}
}
make sure you called this function with parameter Geolocation.requestAuthorization('always') or Geolocation.requestAuthorization('whenInUse')

React Native library to track user location

Which library will be most suitable for Android and iOS to be able to track user location continuously even if the app is running in background.
I need to track user's location to send notification that the user has entered a specific location and upon exiting the user has left the location.
You can use geolocation like this way:
getUserCurrentLocation = async () => {
return new Promise((resolve, reject) => {
try {
navigator.geolocation.getCurrentPosition(position => {
const { latitude, longitude } = position.coords;
resolve({ lat: latitude, lng: longitude })
}, error => {
console.log(`ERROR(${error.code}): ${error.message}`);
resolve({ error })
} // , { enableHighAccuracy: true, timeout: 10000, maximumAge: 1000 }
);
setTimeout(() => { resolve({ error: { code: 3 } }) }, 5000);
} catch (e) {
resolve({ error: { code: 3 } })
}
})
};

How to keep running app even app is close in react-native

I want my app run even app close. or just run when location coordinates changed.
I used appState but it doesnt help me because it works just when appState change.
also I used react-native-background-task but it runs every 7m30s
I use this now but it doesnt help me too. what should I do ?
location(){
this.watchId = navigator.geolocation.watchPosition(
(position) => {
console.log(position.coords.latitude);
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
this.setState({latitude: latitude, longitude: longitude});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 200000, maximumAge: 1000},
);
}
componentDidMount() {
this.location()
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchId);
}