0

App Description:

The AttendanceApp in React Native stores the user's location and status (IN/OUT) in AsyncStorage with the default status as OUT. On opening the app, the user sees a Check In button that triggers the Geolocation API (watchPosition or getCurrentPosition). An if-else statement checks if the user's current location is within a 1-meter radius of their saved location. If the user is within the radius, the AsyncStorage is updated to set the status as IN, and a Check Out page is displayed. Pressing the Check Out button updates the status as OUT, and the user cannot check in or out until the next day. If the user attempts to check in/out, a page displays "YOU ARE ALREADY CHECKED OUT".

App Detailed Description:

I am making an AttendanceApp in React Native in which it is that a user is saved in AsyncStorage with his location (Longitude, Latitude) and a status of "IN" or "OUT" and its by default "OUT". Now I wanna make it like this that when he opens the app he sees a button "Check In" and when he presses that button @react-native-community/geolocation's Geolocation works (watchPosition or getCurrentPosition what ever is good) and there is if else which will tell if the user's current location is in 1 meter radius to his defined location then it changes the AsyncStorage:

Status: "IN"

then I want it to show a "Check Out" page and when user presses the check out button his status is marked

Status: "OUT"

and then till the next day he can't check in or check out only a simple page comes "YOU ARE ALREADY CHECKED OUT".

:

Here comes the main part, when I save the user with longitude and latitude of my location and then when I am on that exact place and match it with the current location again on the Check IN/OUT page it works !!BUT!! even when I am far from the defined location I saved, when I press the buttons of either Check IN/OUT it works even that the location is not same obviously. I need help in this.

Save User Function:

const [Name, setName] = useState('');
const [Age, setAge] = useState(0);
const [Depart, setDepart] = useState('');

const [DisplayLat, setDisplayLat] = useState(0);
const [DisplayLong, setDisplayLong] = useState(0);

const [StringDisplayLat, setStringDisplayLat] = useState('');
const [StringDisplayLong, setStringDisplayLong] = useState('');

useEffect(() => {
    Geolocation.getCurrentPosition(info => {
      setDisplayLat(info.coords.latitude);
      setDisplayLong(info.coords.longitude);
      setStringDisplayLong(info.coords.longitude.toString());
      setStringDisplayLat(info.coords.latitude.toString());
    });
  }, []);

  return (
    <View style={styles.container}>
      <Text>Save User</Text>
      <TextInput placeholder="Name" onChangeText={setName} />
      <TextInput placeholder="Age" onChangeText={setAge} />
      <TextInput placeholder="Depart" onChangeText={setDepart} />
      <TextInput
        placeholder="Long"
        keyboardType="numeric"
        value={StringDisplayLong}
        onChangeText={setStringDisplayLong}
      />
      <TextInput
        placeholder="Lat"
        keyboardType="numeric"
        value={StringDisplayLat}
        onChangeText={setStringDisplayLat}
      />

      <Button
        title="Save"
        onPress={() => {
          AsyncStorage.setItem(
            'user',
            JSON.stringify({
              name: Name,
              age: Age,
              depart: Depart,
              longitude: Number(StringDisplayLong),
              latitude: Number(StringDisplayLat),
            }),
          );
        }}
      />

      <Text>Current Location</Text>
      <Text>Latitude: {DisplayLat}</Text>
      <Text>Longitude: {DisplayLong}</Text>
    </View>
  );
};

Check In Function:

  const distance = 1;

  const checkIn = () => {
    console.log('Check In');
    id = Geolocation.watchPosition(
      position => {
        if (
          position.coords.latitude + distance >= User.latitude &&
          position.coords.latitude - distance <= User.latitude &&
          position.coords.longitude + distance >= User.longitude &&
          position.coords.longitude - distance <= User.longitude
        ) {
          setCurrentLoc({
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
          });

          setMessage('Matched');
          console.log('working');
          setStatus('In');
          AsyncStorage.setItem(
            '@status',
            JSON.stringify({status: 'In', date: new Date()}),
          );
        } else {
          setMessage('NotMatched');
          console.log('not working');
        }
      },
      error => {
        console.error(error);
      },
      {
        enableHighAccuracy: false,
      },
    );
  };

Check Out Function:

  const checkOut = () => {
    AsyncStorage.getItem('@status').then(status => {
      if (status) {
        AsyncStorage.setItem(
          '@UserLog',
          JSON.stringify({
            name: User.name,
            INstatus: JSON.parse(status).status,
            INdate: JSON.parse(status).date,
            OUTstatus: 'Out',
            OUTdate: new Date(),
          }),
        );
      }
    });
    setStatus('AlreadyOut');
    AsyncStorage.setItem(
      '@status',
      JSON.stringify({status: 'AlreadyOut', date: new Date()}),
    );
    Geolocation.stopObserving(id);
    Alert.alert('Check Out', 'You are checked out');
  };

Check IN/OUT Buttons:


useEffect(() => {
    AsyncStorage.getItem('user').then(user => {
      if (user) {
        setUser(JSON.parse(user));
      }
    });

    AsyncStorage.getItem('@status').then(status => {
      if (status) {
        setStatus(JSON.parse(status).status);
        if (JSON.parse(status).date !== new Date()) {
          AsyncStorage.setItem(
            '@status',
            JSON.stringify({status: 'AlreadyOut', date: new Date()}),
          );
          setStatus('AlreadyOut');
        } else {
          AsyncStorage.setItem(
            '@status',
            JSON.stringify({status: 'Out', date: new Date()}),
          );
          setStatus('Out');
        }
      }
    });

    Geolocation.getCurrentPosition(
      position => {
        if (
          position.coords.latitude + distance >= User.latitude &&
          position.coords.latitude - distance <= User.latitude &&
          position.coords.longitude + distance >= User.longitude &&
          position.coords.longitude - distance <= User.longitude
        ) {
          setCurrentLoc({
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
          });
          console.log('Matched');
        } else {
          setCurrentLoc({
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
          });
          console.log('NotMatched');
        }
      },
      error => {
        console.error(error);
      },
      {
        enableHighAccuracy: false,
      },
    );
  }, []);

return (
  <View style={styles.container}>
      {status === 'AlreadyOut' ? (
        <View
          style={{
            height: Dimensions.get('screen').height,
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <Text>You are already checked out</Text>
          <Button
            title="Clear"
            onPress={() => {
              AsyncStorage.clear();
            }}
          />
        </View>
      ) : null}
      {status === 'Out' ? (
        <TouchableOpacity
          onPress={checkIn}
          style={{
            height: Dimensions.get('screen').height / 4,
            borderRadius: 30,
            margin: 30,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: 'green',
          }}>
          <Text>Check In</Text>
        </TouchableOpacity>
      ) : (
        <TouchableOpacity
          onPress={checkOut}
          style={{
            height: Dimensions.get('screen').height / 4,
            borderRadius: 30,
            margin: 30,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: 'tomato',
          }}>
          <Text>Check Out</Text>
        </TouchableOpacity>
      )}
      {Message === 'Matched' ? (
        <View
          style={{
            height: Dimensions.get('screen').height / 4,
            borderRadius: 30,
            margin: 30,
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <Text style={{fontSize: 20}}>  ✅</Text>
          <Text style={{fontSize: 15}}> ! ✅</Text>
        </View>
      ) : null}
      {Message === 'NotMatched' ? (
        <View
          style={{
            height: Dimensions.get('screen').height / 4,
            borderRadius: 30,
            margin: 30,
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <Text style={{fontSize: 20}}>   ❌</Text>
          <Text style={{fontSize: 15}}>  ! ❌</Text>
        </View>
      ) : null}
      <Button
        title="Clear"
        onPress={() => {
          AsyncStorage.clear();
        }}
      />
      <Text>Latitude: {CurrentLoc.latitude}</Text>
      <Text>Longitude: {CurrentLoc.longitude}</Text>

      <Text>User Latitude: {User.latitude}</Text>
      <Text>User Longitude: {User.longitude}</Text>
    </View>
);
CBroe
  • 91,630
  • 14
  • 92
  • 150
  • Please explain further what problem you have, and temper your expectations by researching “geolocation accuracy” – James Apr 11 '23 at 13:25
  • I edited and explained my problem. – Khuzaima Amir Apr 11 '23 at 13:40
  • So what does "far" away actually mean? And have you _checked_ what actual values the Geolocation API returned you for both? Maybe they are not as different as you thought they should be. – CBroe Apr 11 '23 at 13:49
  • 1
    In your if, you check to see if lat and long are within 1 unit of last position. 1 unit is 1 degree. Not 1 meter. 1 degree is huge. – James Apr 11 '23 at 13:54
  • how do i make it 1 meter in if instead of 1 unit – Khuzaima Amir Apr 11 '23 at 13:55
  • 1 meter is much too small to be a detectable change. Geoposition simply isn’t that accurate. – James Apr 11 '23 at 13:58
  • See also https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula – James Apr 11 '23 at 14:02

0 Answers0