I have been trying for hours now to get geolocation.watchPosition() to actually trigger beyond the initial first componentDidMount() trigger. I have read every guide I can find on this and as far as I can see, I am doing everything people suggest.
Here is the code:
componentDidMount() {
this.watchId = navigator.geolocation.watchPosition(
(position) => {
let region = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.02500,
longitudeDelta: 0.01000,
enableHighAccuracy: true
}
this.state.currentLatitude = region.latitude;
this.state.currentLongitude = region.longitude;
console.log("WatchPosition Triggered");
this.onRegionChangeComplete(region, region.latitude, region.longitude);
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 5000, maximumAge: 4000, distanceFilter: 1, useSignificantChanges: false },
);
}
onRegionChangeComplete(region, lastLat, lastLong) {
this.setState({
mapRegion: region,
lastLat: lastLat || this.state.lastLat,
lastLong: lastLong || this.state.lastLong
});
}
I have that console.log in there so I can see every time this function actually triggers in the app, and it just doesn't beyond the first instance of the map screen loading. I have tried walking around, confirming that my location is tracking perfectly, but this function never, ever triggers again.
Have I missed something? I can't find anything different in any example.
Please help if you can, I am pouring hours into this problem.
Related
I am new to mobile development. I am trying to access my current location in the ios simulator running IOS 14.4 and I keep getting the "Location Permission denied" error even after setting up the custom location in the simulator as suggested by some answers on this platform, here. The code that I am running is this
Geolocation.getCurrentPosition(
position => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
coordinates: this.state.coordinates.concat({
latitude: position.coords.latitude,
longitude: position.coords.longitude
})
});
},
error => {
Alert.alert(error.message.toString());
},
{
showLocationDialog: true,
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 0
}
);
I have set up these permissions in my info-plist.
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Description</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Will you allow this app to always know your location?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Do you allow this app to know your current location?</string>
I am not entirely sure what I might be doing wrong here. This is the only code currently that tries to access the location.
Is there any other reason why this error should persist even after setting the current location as the custom location in Features->Location->customlocation? as suggested by the other answers on this platform.
It's required to ask location access permission at run-time before you run code that requires location access.
react-native-permissions is the standard library for cross-platform permissions
Follow installation instruction here - https://www.npmjs.com/package/react-native-permissions
import { request, PERMISSIONS, RESULT } from "react-native-permissions";
function getUserLocation() {
Geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
coordinates: this.state.coordinates.concat({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
}),
});
},
(error) => {
Alert.alert(error.message.toString());
},
{
showLocationDialog: true,
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 0,
}
);
}
request(PERMISSIONS.IOS.LOCATION_ALWAYS).then((result) => {
switch (result) {
case RESULTS.UNAVAILABLE:
console.log(
"This feature is not available (on this device / in this context)"
);
break;
case RESULTS.DENIED:
console.log(
"The permission has not been requested / is denied but requestable"
);
break;
case RESULTS.LIMITED:
console.log("The permission is limited: some actions are possible");
break;
case RESULTS.GRANTED:
console.log("The permission is granted");
// Permission has been granted - app can request location coordinates
getUserLocation();
break;
case RESULTS.BLOCKED:
console.log("The permission is denied and not requestable anymore");
break;
}
});
This package
I need solution for i want to update location every 30 seconds.
I'm using this package for background geolocation updates when its working fine, but when i move my phone (iphone6) it send my location to firebase. I'm using location changes of this package because postTemplate is not working on IOS device and stoOnStillActivity:true for if activity is still it wont send location.
BackgroundGeolocation.configure({
locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
desiredAccuracy: BackgroundGeolocation.MEDIUM_ACCURACY,
stationaryRadius: 10,
distanceFilter: 10,
debug: true,
interval: 30000,
stopOnStillActivity: true,
})
This one sending location to firebase
BackgroundGeolocation.on('location', (location) => {
BackgroundGeolocation.startTask(taskKey => {
firestore()
.collection('testlocation')
.add({
name: 'DEVICE',
lat: location.latitude,
lon: location.longitude,
dat: new Date,
})
.then(() => {
console.log('Location added BITCH!')
}).catch(e => console.log(e))
console.log("Stark task started successfully", new Date, location.latitude, location.longitude)
BackgroundGeolocation.endTask(taskKey)
})
})
Currently trying to build a location based triggered local notification in ionic 4 - I started by using native background mode (implemented in the initialize App of app.ts) which is working and tracking user location with the watchPosition(). However I'm finding it hard to get the trigger of the local notification to work. My code that I have tried is attached, ant help would be much appreciated!
this.backgroundMode.on('activate').subscribe(() => {
console.log('activated');
const watchLocation = this.geolocation.watchPosition();
watchLocation.subscribe((data) => {
data.coords.latitude;
data.coords.longitude;
console.log('current Position', data.coords.latitude, data.coords.longitude);
this.locationNotification();
});
});
this.backgroundMode.enable();
}
locationNotification() {
this.localNotifcation.schedule({
id: 3,
title: 'Welcome to the show grounds!',
text: 'Click me to declare your entries!!',
sound: '',
trigger: {
type: 'location',
center: [53.3385394, -6.266703],
radius: 1000,
notifyOnEntry: true,
notifyOnExit: false,
single: true
},
vibrate: true,
foreground: true
});
}
When showing my web push notifications, I'm adding an action in my options so user can ask to get notified again in 30 minutes.
const options = {
...,
actions: [
{
action: 'remind-action',
title: 'Remind again in 30',
icon: '/remind.png'
}
],
....
}
and then I handle the action in service worker:
self.addEventListener('notificationclick', function(event) {
if (!event.action) return
switch (event.action) {
...
case 'remind-action':
event.notification.close()
event.waitUntil(
new Promise((resolve, reject) => {
setTimeout(() => {
const options = {
...
actions: [
{
action: 'remind-action',
title: 'Remind again in 30',
icon: '/remind.png'
}
],
...
}
self.registration.showNotification('Reminder', options)
resolve(true)
}, 30 * 60 * 1000)
})
)
break
}
})
If only there was a way to re-emit the push event.
The issue with the above code is that it won't show the notification after 30 minutes, however if I set the timeout to 1 minute it works just fine.
I think some where Chrome is ignoring event.waitUntill and killing the setTimeout.
What is causing this and how can I resolve this?
The browser will automatically and on purpose throttle your setTimeouts to prevent abuse and eg. tracking of the user. Put it another way, you cannot implement what you want solely on the client side.
To show the notification again (reliably), you need to send it again from the server. You would ofc inform the server that the user wants to be reminded in x minutes or so.
Building an app with RN I use the following to receive user's location :
navigator.geolocation.getCurrentPosition(
(position) => {
//do stuff with location
},
(error) => {
//error or locaiton not allowed
},
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
Which immediately invokes the inquiry for user to accept geolocation permissions. What I'm trying to achieve now is to have an explicit screen before prompting user to click on a button to accept those permissions. In order to get there, I need some way to check if he has accepted those permissions before or not. Caching it in storage would be a bad solution - it might go out of sync if user changes permissions in settings.
How can I check if user has accepted geolocation permissions without triggering the permission alert?
You can use this library https://github.com/yonahforst/react-native-permissions to check if user has accepted location permission.
Like this:
Permissions.getPermissionStatus('location')
.then(response => {
this.setState({ locationPermission: response })
})
In v2.x.x of react-native-permissions (https://github.com/react-native-community/react-native-permissions)
import { Platform } from "react-native";
import { PERMISSIONS, request } from "react-native-permissions";
import * as Geolocation from "#react-native-community/geolocation";
try {
request(
Platform.select({
android: PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
})
).then(res => {
if (res == "granted") {
Geolocation.getCurrentPosition( // do location staffs);
Geolocation.watchPosition( // do watch location staffs );
} else {
// console.log("Location is not enabled");
}
});
} catch (error) {
console.log("location set error:", error);
}
Check this library, this would help you to check location is enabled or not.
https://www.npmjs.com/package/react-native-device-info#isLocationEnabled
Note : Above will not check permission enabled on not. It will just check location truned on or not