michalchudziak / react-native-geolocation

Geolocation APIs for React Native
MIT License
1.31k stars 228 forks source link

The error callback of getCurrentPosition doesn't run when location services are turned off #251

Open Molitvan opened 1 year ago

Molitvan commented 1 year ago

Environment

System: OS: Windows 10 10.0.22623 CPU: (12) x64 AMD Ryzen 5 3600 6-Core Processor Memory: 6.95 GB / 15.94 GB Binaries: Node: 19.3.0 - C:\Program Files\nodejs\node.EXE Yarn: Not Found npm: 9.2.0 - C:\Program Files\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: API Levels: 33, 33 Build Tools: 30.0.3, 33.0.0, 33.0.2 System Images: android-15 | Google APIs ARM EABI v7a, android-18 | Google APIs ARM EABI v7a, android-30 | Wear OS 3 Int Android NDK: Not Found Windows SDK: Not Found IDEs: Android Studio: AI-221.6008.13.2211.9619390 Visual Studio: Not Found Languages: Java: 17.0.6 npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.6 => 0.71.6 react-native-windows: Not Found npmGlobalPackages: react-native: Not Found

Platforms

Android

Versions

Description

When I call the getCurrentPosition method, and pass it an error callback as a second argument, I expect it to be ran when the location services are turned off. However, nothing happens.

Reproducible Demo

import { Button } from 'react-native'
import Location from '@react-native-community/geolocation'

export default function App() {
    async function getLocation() {
        await Location.getCurrentPosition((position) => {
            console.log(position.coords)
        }, (error) => {
            console.log('Unable to get your location!')
        }, { enableHighAccuracy: true, maximumAge: 1000 })
    }

    return (
        <Button title="Get location" onPress={getLocation} />
    )
}
umer-zz commented 1 year ago

remove async/await. Use it as a normal callback. getCurrentPosition doesn't return promise so you can't use async/await syntax.

import { Button } from 'react-native'
import Location from '@react-native-community/geolocation'

export default function App() {
    function getLocation() {
        Location.getCurrentPosition((position) => {
            console.log(position.coords)
        }, (error) => {
            console.log('Unable to get your location!')
        }, { enableHighAccuracy: true, maximumAge: 1000 })
    }

    return (
        <Button title="Get location" onPress={getLocation} />
    )
}
Molitvan commented 1 year ago

Thanks for the quick reply. I removed async/await, but it still doesn't work. Am I missing something?

This is my code:

    function createStop() {
        Location.getCurrentPosition(async (currentPosition) => {
            map.stops.push({ name: nameInput, longitude: currentPosition.coords.longitude, latitude: currentPosition.coords.latitude })

            await AsyncStorage.setItem(map.id, JSON.stringify(map))
            .then(() => navigation.goBack())
            .catch((error) => console.log(error))
        }, (error) => {
            setShowLocationNotAvailableError(true)
            console.log(error)
        }, { enableHighAccuracy: true, maximumAge: 1000 })
    }

This createStop function runs from onPress event of TouchableNativeFeedback. Also, I tried playing with the timeout option, but with no luck.

umer-zz commented 1 year ago

implement try catch

function createStop() {
  Location.getCurrentPosition(async (currentPosition) => {
    map.stops.push({ name: nameInput, longitude: currentPosition.coords.longitude, latitude: currentPosition.coords.latitude })

    try {

      await AsyncStorage.setItem(map.id, JSON.stringify(map))
      navigation.goBack()
    }
    catch (err) {
      console.log(err)
    }
  }, (error) => {
    setShowLocationNotAvailableError(true)
    console.log(error)
  }, { enableHighAccuracy: true, maximumAge: 1000 })
}
Molitvan commented 1 year ago

Still doesn't work, but thank you for your reply. I guess I just won't have that warning in my app, it isn't a big deal anyway. Also, for some reason, it works perfectly fine with the watchPosition method. Maybe I'll try to fix it myself when I have time.

michalchudziak commented 1 year ago

Thanks for reporting. I will look onto this issue when I'll have some time, however if you'd like to help, I encourage to send a PR.

ddcrobert commented 1 year ago

I had a similar issue when you produce multiple calls to Geolocation.getCurrentPosition. It maybe not be on purpose, e.g. in my case, a prev dev had place it into a useEffect block, leading to two-three calls to this function. I wasn't getting an error callback for permission until I added a flag to ensure it was called only once.

Reisclef commented 8 months ago

I also have this issue. Works fine if location servies are on. If they are turned off on the device (samsung A32), I would expect this to return an error saying location services aren't available. Instead, it just times out.