React Native Geolocation.watchPosition not working in Android emulator - react-native

It's crucial for me to have location updates and emulation of a route in the android emulator. But all I get is a single update on the map and nothing more.
Can't seem to find any good examples of "watchPosition" using functional components.
What am I missing? Here's some of the code I'm using:
...
import Geolocation from "#react-native-community/geolocation";
...
useEffect(() => {
const watchId = Geolocation.watchPosition(
handlePosition,
handlePositionError,
geoConfig
);
return () => Geolocation.clearWatch(watchId);
}, []);
const geoConfig = {
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 1000,
};
const handlePosition = info => {
console.log("getting position");
setMyLocation({
latitude: info.coords.latitude,
longitude: info.coords.longitude,
latitudeDelta: latitudeDelta,
longitudeDelta: longitudeDelta,
});
if (isMine) {
const position = {
latitude: info.coords.latitude,
longitude: info.coords.longitude,
};
updateRideDriverPosition(ride.rideId, position, () =>
console.log("Yay! position updated")
);
} else {
(async () =>
await getRideById(ride.rideId).then(item => {
setCarLocation({
latitude: item.position.latitude,
longitude: item.position.longitude,
});
}))();
}
};
const handlePositionError = error => console.log(new Date(), error);
...
I tried to just use "getPosition" inside an interval and that worked fine, also the google maps app works fine and updates the location the whole route I configured.
How can I get continuous responses with new locations?

Related

Check location access granted globally

I want to check whether the location is active throughout the app. I'm currently using the following custom hook placed in the parent component of my navigation container.
But I don't get the location model appearing.
Following is the code that appear in the component.
const [locationAccessGranted, currentLocation] = useLocation();
const [visible, setVisible] = useState(true);
useEffect(() => {
!locationAccessGranted ? setVisible(true) : setVisible(false);
}, [locationAccessGranted]);
return (
<>
<RootNavigation />
<Modal visible={visible}>
<Text>Please Enable location</Text>
</Modal>
</>
)
My hooks code (useLocation)
function useLocation() {
const [locationAccessGranted, setLocationAccessGranted] = useState(null);
const [currentLocation, setCurrentLocation] = useState({
latitude: null,
longitude: null,
});
useEffect(() => {
const grantLocationAccess = async () => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
'title': 'App Location Permission',
'message': 'App needs access to your location ',
});
setLocationAccessGranted(granted);
if (granted) {
Geolocation.getCurrentPosition((position) => {
const { latitude, longitude } = position.coords;
setCurrentLocation({ latitude: latitude.toString(), longitude: longitude.toString() });
}, (error) => {
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
}
};
grantLocationAccess();
}, []);
return [locationAccessGranted, currentLocation];
}

current location works perfect with long and lat null values, however not with IOS?

I want to get my current location on a map on IOS, however long: null and lat: null, both seem to get the current location on a map for android but do not work for IOS, what do I do to get the current location on IOS ? below is the code, for example my initial region is lat:null, and long: null, however on android i get the current location, however on ios i do not
class MapScreen extends Component {
//Set the HeaderTitle screen
static navigationOptions = props => {
const placeName = props.navigation.getParam("placeName");
return { headerTitle: placeName.toUpperCase() };
};
constructor(props) {
super(props);
//Initial State
this.state = {
lat: null,
long: null,
places: [],
isLoading: false,
placeType: "restaurant"
};
}
componentDidMount() {
console.log(this.props);
const { navigation } = this.props;
const placeType = navigation.getParam("placeType");
this.setState({ placeType: placeType });
this.getCurrentLocation();
}
/**
* Get current user's position
*/
getCurrentLocation() {
navigator.geolocation.getCurrentPosition(position => {
const lat = position.coords.latitude;
const long = position.coords.longitude;
this.setState({ lat: lat, long: long });
this.getPlaces();
});
}
/**
* Get the Place URL
*/
getPlacesUrl(lat, long, radius, type, apiKey) {
const baseUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?`;
const location = `location=${lat},${long}&radius=${radius}`;
const typeData = `&types=${type}`;
const api = `&key=${apiKey}`;
return `${baseUrl}${location}${typeData}${api}`;
}
getPlaces() {
const { lat, long, placeType } = this.state;
const markers = [];
const url = this.getPlacesUrl(lat, long, 1500, placeType, GOOGLE_API_KEY);
fetch(url)
.then(res => res.json())
.then(res => {
res.results.map((element, index) => {
const marketObj = {};
marketObj.id = element.id;
marketObj.name = element.name;
marketObj.photos = element.photos;
marketObj.rating = element.rating;
marketObj.vicinity = element.vicinity;
marketObj.marker = {
latitude: element.geometry.location.lat,
longitude: element.geometry.location.lng
};
markers.push(marketObj);
});
//update our places array
this.setState({ places: markers });
});
}
render() {
const { lat, long, places } = this.state;
return (
<View style={styles.container}>
<View style={styles.mapView}>
<MapView
style={{
flex: 1
}}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: lat,
longitude: long,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}}
>
{places.map((marker, i) => (
<MapView.Marker
key={i}
coordinate={{
latitude: marker.marker.latitude,
longitude: marker.marker.longitude
}}
title={marker.name}
/>
))}
</MapView>
did you tried react-native-geolocation-service
React native geolocation service for iOS and android.
Why ?
This library is created in an attempt to fix the location timeout issue on android with the react-native's current implementation of Geolocation API. This library tries to solve the issue by using Google Play Service's new FusedLocationProviderClient API, which Google strongly recommends over android's default framework location API. It automatically decides which provider to use based on your request configuration and also prompts you to change the location mode if it doesn't satisfy your current request configuration.
NOTE: Location request can still timeout since many android devices have GPS issue in the hardware level or in the system software level. Check the FAQ for more details.

React Native undefined is not an object (evaluating 'response Json.results[0].formatted_address')

While running React apps in android mobile
Console
undefined is not an object (evaluating
'responseJson.results[0].formatted_address')
* src\screens\MapScreen.js:194:55 in <unknown>
- node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
- node_modules\promise\setimmediate\core.js:123:25 in <unknown>
- ... 8 more stack frames from framework internals
While running React apps in android mobile
check this
undefined is not an object (evaluating
'responseJson.results[0].formatted_address')
* src\screens\MapScreen.js:194:55 in <unknown>
- node_modules\promise\setimmediate\core.js:37:14 in tryCallOne
- node_modules\promise\setimmediate\core.js:123:25 in <unknown>
- ... 8 more stack frames from framework internals
_getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== 'granted') {
this.setState({
errorMessage: 'Permission to access location was denied',
});
}
let location = await Location.getCurrentPositionAsync({})
if(location){
var pos = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
};
var curuser = firebase.auth().currentUser.uid;
if(pos){
let latlng = pos.latitude + ','+pos.longitude;
return fetch('https://maps.googleapis.com/maps/api/geocode/json?latlng='+latlng+'&key=AIzaSyDZ7HSZZafEkBmuwD2CdHrLJNn3kEm39Fo')
.then((response) => response.json())
.then((responseJson) => {
if(this.passData.wherelatitude == 0){
this.setState({
whereText: responseJson.results[0].formatted_address,
region: {
latitude: pos.latitude,
longitude: pos.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
},()=>{
this.forceUpdate();
this.showDriver();
this.passData.wherelatitude = pos.latitude
this.passData.wherelongitude = pos.longitude
this.passData.whereText = responseJson.results[0].formatted_address;
firebase.database().ref('users/' + curuser+'/location').update({
add:responseJson.results[0].formatted_address,
lat:pos.latitude,
lng:pos.longitude
})
});
}else{
this.forceUpdate();
this.showDriver();
this.passData.wherelatitude = pos.latitude
this.passData.wherelongitude = pos.longitude
this.passData.whereText = responseJson.results[0].formatted_address;
firebase.database().ref('users/' + curuser+'/location').update({
add:responseJson.results[0].formatted_address,
lat:pos.latitude,
lng:pos.longitude
})
}
})
.catch((error) =>{
console.error(error);
});
}
}
}

get current user location using google maps api with react native?

i'm currently working on a project using google maps api with react native, but i'm struggling to handle get current user location with redux, this is my action ,how can i fix it :
import MAPSActionTypes from "./mapsactiontypes";
export const currentlocation = () => {
return navigator.geolocation.getCurrentPosition(
(position) => {
console.log("wokeeey");
console.log(position);
{payload: position}
},
(error) => console.log(error)),
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 },
};
I'm not sure what you're error is exactly, but I found an issue here on doing the exact same thing. It referred to a code sample you can find here, which I've reproduced below.
import React from 'react';
import {
Alert,
Platform,
StyleSheet
} from 'react-native';
import MapView from 'react-native-maps'
const LATITUDE_DELTA = 0.01;
const LONGITUDE_DELTA = 0.01;
const initialRegion = {
latitude: -37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
class MyMapView extends React.Component {
map = null;
state = {
region: {
latitude: -37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
},
ready: true,
filteredMarkers: []
};
setRegion(region) {
if(this.state.ready) {
setTimeout(() => this.map.mapview.animateToRegion(region), 10);
}
//this.setState({ region });
}
componentDidMount() {
console.log('Component did mount');
this.getCurrentPosition();
}
getCurrentPosition() {
try {
navigator.geolocation.getCurrentPosition(
(position) => {
const region = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
};
this.setRegion(region);
},
(error) => {
//TODO: better design
switch (error.code) {
case 1:
if (Platform.OS === "ios") {
Alert.alert("", "Para ubicar tu locación habilita permiso para la aplicación en Ajustes - Privacidad - Localización");
} else {
Alert.alert("", "Para ubicar tu locación habilita permiso para la aplicación en Ajustes - Apps - ExampleApp - Localización");
}
break;
default:
Alert.alert("", "Error al detectar tu locación");
}
}
);
} catch(e) {
alert(e.message || "");
}
};
onMapReady = (e) => {
if(!this.state.ready) {
this.setState({ready: true});
}
};
onRegionChange = (region) => {
console.log('onRegionChange', region);
};
onRegionChangeComplete = (region) => {
console.log('onRegionChangeComplete', region);
};
render() {
const { region } = this.state;
const { children, renderMarker, markers } = this.props;
return (
<MapView
showsUserLocation
ref={ map => { this.map = map }}
data={markers}
initialRegion={initialRegion}
renderMarker={renderMarker}
onMapReady={this.onMapReady}
showsMyLocationButton={false}
onRegionChange={this.onRegionChange}
onRegionChangeComplete={this.onRegionChangeComplete}
style={StyleSheet.absoluteFill}
textStyle={{ color: '#bc8b00' }}
containerStyle={{backgroundColor: 'white', borderColor: '#BC8B00'}}>
{markers.map(renderMarker)}
{children && children || null}
</ClusteredMapView>
);
}
}
export default MyMapView;

How to render markers on map fetched from API?

I need your help to know how to render markers on map fetched from API.
I want to track a person's location from gps coordinates (longitude and latitude) by getting data from API.
I tried too much to recover the coordinates in the MapView but I did not arrive to do it.
This is my code :
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import MapView from 'react-native-maps';
export default class App extends React.Component {
mapMarkers() {
return fetch('http://first-ontheweb.com/onLineSenior/pos.php')
.then(response => response.json())
.then(responseJson => {
this.setState({
marker: responseJson.data,
});
console.log(responseJson);
return responseJson.data;
})
.catch(error => {
console.error(error);
});
}
componentDidMount() {
this.mapMarkers();
navigator.geolocation.getCurrentPosition(
position => {
console.log('getCurrentPosition Succes');
this.setState({
region: {
...this.state.region,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
},
});
this.watchPosition();
},
error => {
this.props.displayError('Error detecting your Location');
alert(JSON.stringify(error));
},
{ enableHightAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
watchPosition() {
this.watchID = navigator.geolocation.watchPosition(
position => {
console.log('Watch Position Succes');
if (this.props.followUser) {
this.map.animateToRegion(
this.newRegion(position.coords.latitude, position.coords.longitude)
);
}
},
error => {
this.props.displayError('Error detecting your location');
},
{ enableHightAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
onRegionChange(region) {
this.setState({ region });
}
constructor(props) {
super(props);
this.state = {
region: {
latitude: -6.914744,
longitude: 107.60981,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
},
markers: [
{
latlng: { latitude: marker.latitude, longitude: marker.longitude },
},
],
};
this.onRegionChange = this.onRegionChange.bind(this);
}
render() {
return (
<MapView
style={styles.map}
showsUserLocation={true}
followUserLocation={true}
zoomEnabled={true}
//annotations={markers}
>
{this.state.markers.map((marker, index) => (
<MapView.Marker
key={index}
coordinate={marker.latlng} />
))}
</MapView>
);
}
}
const styles = StyleSheet.create({
map: {
...StyleSheet.absoluteFillObject,
},
});
This is the error:
ESLint: (76:59) 'marker' is not defined. (no-undef)
So, I want to display the GPS coordinates in the MapView by getting data from API.
I think its a typo
in setState it should be markers not marker
this.setState({
markers: responseJson.data,
});
Try this code, I have changed it, now working fine
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import MapView from 'react-native-maps';
export default class App extends React.Component {
mapMarkers() {
return fetch('http://first-ontheweb.com/onLineSenior/pos.php')
.then(response => response.json())
.then(responseJson => {
this.setState({
markers: responseJson,
});
console.log(responseJson);
return responseJson;
})
.catch(error => {
console.error(error);
});
}
componentDidMount() {
this.mapMarkers();
navigator.geolocation.getCurrentPosition(
position => {
console.log('getCurrentPosition Succes');
this.setState({
region: {
...this.state.region,
latitude: position.coords.latitude,
longitude: position.coords.longitude,
},
});
this.watchPosition();
},
error => {
this.props.displayError('Error detecting your Location');
alert(JSON.stringify(error));
},
{ enableHightAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
watchPosition() {
this.watchID = navigator.geolocation.watchPosition(
position => {
console.log('Watch Position Succes');
if (this.props.followUser) {
this.map.animateToRegion(
this.newRegion(position.coords.latitude, position.coords.longitude)
);
}
},
error => {
this.props.displayError('Error detecting your location');
},
{ enableHightAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
onRegionChange(region) {
this.setState({ region });
}
constructor(props) {
super(props);
this.state = {
region: {
latitude: -6.914744,
longitude: 107.60981,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
},
markers: []
};
this.onRegionChange = this.onRegionChange.bind(this);
}
render() {
console.log('marker', this.state.markers)
return (
<MapView
initialRegion={this.state.region}
style={styles.map}
showsUserLocation={true}
followUserLocation={true}
showsMyLocationButton={true}
//annotations={markers}
>
{this.state.markers && this.state.markers.map((marker, index) => (
<MapView.Marker
key={index}
coordinate={{
latitude: Number(marker.latitude),
longitude: Number(marker.longitude),
}}
/>
))}
</MapView>
);
}
}
const styles = StyleSheet.create({
map: {
...StyleSheet.absoluteFillObject,
},
});