React Native library to track user location - react-native

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 } })
}
})
};

Related

I want to get currentlocation of user , I am getting current location in android and ios but not on android tablet

I am getting correct latitude and longitude in android and ios and showing the marker but this doesn't happen on tablet. I am not getting marker in tablet android , I have enable showUserLocation={true} as well.
useEffect(() => {
const requestLocationPermission = async () => {
if (Platform.OS === 'ios') {
Geolocation.requestAuthorization('always').then((resp) => {
console.log("ios response ", resp)
Geolocation.getCurrentPosition(
(position) => {
console.log("position:::", position)
const { latitude, longitude } = position.coords;
setCurrentLatitude(latitude)
setCurrentLongitude(longitude)
},
(error) => {
// See error code charts below.
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 20000 }
);
}).catch((e) => console.log("ios error ::", e))
}
else {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Access Required',
message: 'This App needs to Access your location',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
Geolocation.getCurrentPosition(
(position) => {
// console.log("position:::", position)
const { latitude, longitude } = position.coords;
setCurrentLatitude(latitude)
setCurrentLongitude(longitude)
},
(error) => {
// See error code charts below.
console.log(error.code, error.message);
},
{ enableHighAccuracy: false, timeout: 20000 }
);
} else {
setLocationStatus('Permission Denied');
}
} catch (err) {
console.warn("Location error ::", err);
}
};
}
requestLocationPermission();
}, [])
This is what I have done

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 async getting data when running app first time

I have two components, in first components storing data in asyncstorage, in second component display data, when install app and save data does not get data from asyncstorage, when open app second time data are displayed.
storeData = async (item, messave, messrem) => {
const checkarary = this.state.favorite;
if(checkarary.some(e => e.name === item.name)) {
const value = this.state.favorite;
const position = value.filter((lists) => lists.id !== item.id);
this.setState({
favorite: position
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
Toast.show({
text: messrem,
buttonText: "Okay",
duration: 3000,
type: "danger"
});
});
} catch (error) {
}
});
} else {
this.setState({
favorite: [...this.state.favorite, item]
}, () => {
try {
AsyncStorage.setItem('favoriti', JSON.stringify(this.state.favorite), () => {
// AsyncStorage.getItem('favoriti', (err, result) => {
// console.log(result);
// });
Toast.show({
text: messave,
buttonText: "Okay",
duration: 3000,
type: "success"
});
});
} catch (error) {
}
});
}
};
Getting data in second component
_retrieveData = async () => {
try {
AsyncStorage.getItem('favoriti').then((value) => {
const parsed = JSON.parse(value);
this.setState({ favorite: parsed })
})
} catch (error) {
}
};
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
componentDidUpdate() {
this._retrieveData();
};
How fix this issue, is there some solution. Can I set Item and reload app when install app or somthing else.
Use this
componentWillMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
instead of
componentDidMount() {
this._retrieveData();
setTimeout(() => {
this.setState({
loading: false,
})
}, 2000)
};
As componentWillMount is called after constructor is called for class and componentDidMount is called after screen is once rendered.

navigator.geolocation:: Location request timed out issue 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},
);

React-redux action is returning before async action is complete

I have a React Native app using redux and I'd like my action to set the GPS coordinates so I have them available in the store. You can see my console logs in the code, and 'action returning' is logged before 'has coordinates', which is the problem.
Component:
<TouchableOpacity style={{flex:1}} onPress={() => {
this.props.setLocation();
}}>
Action.js
export function setLocation(){
let coords = {
latitude:0,
longitude:0,
navigatorError:''
};
navigator.geolocation.getCurrentPosition(
(position) => {
console.log('has coordinates');
coords['latitude'] = position.coords.latitude
coords['longitude'] = position.coords.longitude
coords['navigatorError'] = null
},
(error) => coords['navigatorError'] = error.message,
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
console.log('action returning');
return {
type: 'set_location',
payload: coords
};
};
Reducer.js
export default (state = null, action) => {
switch(action.type){
case 'set_location':
return action.payload;
default:
return state;
}
}
Note: I'm not actually using redux-thunk in this project, I'm not sure if it's appropriate for what I need here.
You can use async and await to accomplish this. Basically, you need to await the coords to be returned from your asynchronous call.
Something like this:
export async function setLocation(){
let coords = {
latitude:0,
longitude:0,
navigatorError:''
};
await navigator.geolocation.getCurrentPosition(
(position) => {
console.log('has coordinates');
coords['latitude'] = position.coords.latitude
coords['longitude'] = position.coords.longitude
coords['navigatorError'] = null
},
(error) => coords['navigatorError'] = error.message,
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
console.log('action returning');
return {
type: 'set_location',
payload: coords
};
};
Documentation on async/await can be found here.