React Native: The access prompt to use coordinates is being activated when entering the application

19 views Asked by At

I have the situation that when entering the application for the first time the locality activation modal is being executed. And that case should not occur when entering the application.

Any way to prevent the application from asking me for access to the coordinates as soon as the app loads?

The getLocation function is being executed when you enter the application for the first time.

import React, {
  createContext,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';
import {AppState} from 'react-native';
import Geolocation, {
  GeolocationError,
  GeolocationOptions,
  GeolocationResponse,
} from '@react-native-community/geolocation';

const PERMISSION_DENIED = 1;

export type GeolocationContextProps = {
  coords: {
    latitude: number;
    longitude: number;
  };
  error?: string | null | number;
  distance?: number;
};

const GeolocationContext = createContext<GeolocationContextProps | undefined>(
  undefined,
);

export const useGeolocation = () => {
  const context = useContext(GeolocationContext);
  if (!context) {
    throw new Error('useGeolocation must be used within a GeolocationProvider');
  }
  return context;
};

export const GeolocationProvider: React.FC<{
  children: React.ReactNode;
  geolocationOptions?: GeolocationOptions;
}> = ({children, geolocationOptions = {}}) => {
  const [location, setLocation] = useState<GeolocationContextProps>({
    coords: {
      latitude: 0,
      longitude: 0,
    },
    error: null,
    distance: 0,
  });

  const appStateRef = useRef<string>('active');

  useEffect(() => {
    const handleSuccess = (position: GeolocationResponse) => {
      const {latitude, longitude} = position.coords;
      setLocation(prevLocation => ({
        coords: {latitude, longitude},
        error: null,
        distance: prevLocation.distance || 0,
      }));
    };

    const handleError = (error: GeolocationError) => {
      console.error('handleError::error', error);

      if (error.code === PERMISSION_DENIED) {
        setLocation({
          coords: {latitude: 0, longitude: 0},
          error: PERMISSION_DENIED,
          distance: location.distance || 0,
        });
      } else {
        setLocation({
          coords: {latitude: 0, longitude: 0},
          error: error.message,
          distance: location.distance || 0,
        });
      }
    };

    const getLocation = async () => {
      try {
        console.log("heyy!");

        // Assume permissions are already granted
        Geolocation.getCurrentPosition(handleSuccess, handleError, {
          ...geolocationOptions,
        });
      } catch (error) {
        console.error('Location Permission Error:', error);
        if ((error as any).code === PERMISSION_DENIED) {
          setLocation({
            coords: {latitude: 0, longitude: 0},
            error: PERMISSION_DENIED,
            distance: location.distance || 0,
          });
        } else {
          setLocation({
            coords: {latitude: 0, longitude: 0},
            error: 'Location permission error.',
            distance: location.distance || 0,
          });
        }
      }
    };

    const handleAppStateChange = (nextAppState: string) => {
      if (nextAppState === 'active' && appStateRef.current === 'background') {
        getLocation();
      }

      appStateRef.current = nextAppState;
    };

    const appStateSubscription = AppState.addEventListener(
      'change',
      handleAppStateChange,
    );

    // Request location only when the component mounts
    getLocation();

    return () => {
      appStateSubscription.remove();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <GeolocationContext.Provider value={location}>
      {children}
    </GeolocationContext.Provider>
  );
};

App.tsx

const watchPositionOptions: GeolocationOptions = {
  distanceFilter: 200,
  enableHighAccuracy: true,
  fastestInterval: 15000,
  interval: 15000,
  maximumAge: 100,
  timeout: 300000,
};

<Provider store={store}>
      <ReduxProvider>
        <GeolocationProvider geolocationOptions={{...watchPositionOptions}}>
          <HomeAdventureProvider>
            <EventProvider>
              <OfferProvider>
                <GestureHandlerRootView style={{flex: 1}}>
                  <QueryClientProvider client={queryClient}>
                    <SafeAreaProvider style={{backgroundColor: 'lightBlue'}}>
                      <NavigationContainer linking={linking}>
                        <RootNavigation />
                      </NavigationContainer>
                    </SafeAreaProvider>
                  </QueryClientProvider>
                </GestureHandlerRootView>
              </OfferProvider>
            </EventProvider>
          </HomeAdventureProvider>
        </GeolocationProvider>
      </ReduxProvider>
    </Provider>
0

There are 0 answers