Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to use background geo location service in react-native

Tags:

I have just started learning react-native

I have

  • App.js
  • Navigation.js

I have two screens

  • SplashScreen.js

  • Login.js

On App.js

const App = () => (
  <Nav  />
);

export default App;

Navigation.js

const Nav = createStackNavigator({
    loginScreen: { screen: Login },
    splashScreen: {screen: SplashScreen}
},
{ 
    initialRouteName: 'splashScreen',
})
export default createAppContainer(Nav);

On splashscreen.js

componentWillMount(){
    setTimeout(() => {
        this.props.navigation.navigate("loginScreen");
    }, 3000);
}

Till now everything is working perfectly

Now I have started implementing background geo location tracking using

https://github.com/mauron85/react-native-background-geolocation/tree/0.4-stable

And for testing I have placed this in login.js

import React, { Component } from "react";
import Contacts from 'react-native-contacts';
import { Image, StyleSheet, Text, TouchableOpacity, View, Button, PermissionsAndroid } from "react-native";
import { appContainer, buttons } from '../StyleSheet'
import firebase from '../FireBaseSetup/Firebase'
import BackgroundTimer from 'react-native-background-timer';

import BackgroundGeolocation from 'react-native-mauron85-background-geolocation';

class Login extends Component {

    constructor(props) {
        super(props);
        this.state = {
            phonecontacts: null,
            region: null,
            locations: [],
            stationaries: [],
            isRunning: false
        };

    }

    componentDidMount() {
        console.log('map did mount');

        function logError(msg) {
          console.log(`[ERROR] getLocations: ${msg}`);
        }

        const handleHistoricLocations = locations => {
          let region = null;
          const now = Date.now();
          const latitudeDelta = 0.01;
          const longitudeDelta = 0.01;
          const durationOfDayInMillis = 24 * 3600 * 1000;

          const locationsPast24Hours = locations.filter(location => {
            return now - location.time <= durationOfDayInMillis;
          });

          if (locationsPast24Hours.length > 0) {
            // asume locations are already sorted
            const lastLocation =
              locationsPast24Hours[locationsPast24Hours.length - 1];
            region = Object.assign({}, lastLocation, {
              latitudeDelta,
              longitudeDelta
            });
          }
          this.setState({ locations: locationsPast24Hours, region });
          //firebase.firestore().collection('locations').add({ locations: [lastLocation], region })  
        };

        // BackgroundGeolocation.getValidLocations(
        //   handleHistoricLocations.bind(this),
        //   logError
        // );

        BackgroundGeolocation.getCurrentLocation(lastLocation => {
          let region = this.state.region;
          const latitudeDelta = 0.01;
          const longitudeDelta = 0.01;
          region = Object.assign({}, lastLocation, {
            latitudeDelta,
            longitudeDelta
          });
          this.setState({ locations: [lastLocation], region });
          firebase.firestore().collection('locations').add({ locations: [lastLocation], region })   
        }, (error) => {
          setTimeout(() => {
            Alert.alert('Error obtaining current location', JSON.stringify(error));
          }, 100);
        });

        BackgroundGeolocation.on('start', () => {
          // service started successfully
          // you should adjust your app UI for example change switch element to indicate
          // that service is running
          console.log('[DEBUG] BackgroundGeolocation has been started');
          this.setState({ isRunning: true });
        });

        BackgroundGeolocation.on('stop', () => {
          console.log('[DEBUG] BackgroundGeolocation has been stopped');
          this.setState({ isRunning: false });
        });

        BackgroundGeolocation.on('authorization', status => {

          console.log(
            '[INFO] BackgroundGeolocation authorization status: ' + status
          );
          if (status !== BackgroundGeolocation.AUTHORIZED) {
            // we need to set delay after permission prompt or otherwise alert will not be shown
            setTimeout(() =>
              Alert.alert(
                'App requires location tracking',
                'Would you like to open app settings?',
                [
                  {
                    text: 'Yes',
                    onPress: () => BackgroundGeolocation.showAppSettings()
                  },
                  {
                    text: 'No',
                    onPress: () => console.log('No Pressed'),
                    style: 'cancel'
                  }
                ]
            ), 1000);
          }
        });

        BackgroundGeolocation.on('error', ({ message }) => {
          Alert.alert('BackgroundGeolocation error', message);
        });

        BackgroundGeolocation.on('location', location => {
          console.log('[DEBUG] BackgroundGeolocation location', location);
          BackgroundGeolocation.startTask(taskKey => {
            requestAnimationFrame(() => {
              const longitudeDelta = 0.01;
              const latitudeDelta = 0.01;
              const region = Object.assign({}, location, {
                latitudeDelta,
                longitudeDelta
              });
              const locations = this.state.locations.slice(0);
              locations.push(location);
              this.setState({ locations, region });
              BackgroundGeolocation.endTask(taskKey);
            });
          });
        });

        BackgroundGeolocation.on('stationary', (location) => {
          console.log('[DEBUG] BackgroundGeolocation stationary', location);
          BackgroundGeolocation.startTask(taskKey => {
            requestAnimationFrame(() => {
              const stationaries = this.state.stationaries.slice(0);
              if (location.radius) {
                const longitudeDelta = 0.01;
                const latitudeDelta = 0.01;
                const region = Object.assign({}, location, {
                  latitudeDelta,
                  longitudeDelta
                });
                const stationaries = this.state.stationaries.slice(0);
                stationaries.push(location);
                this.setState({ stationaries, region });
              }
              BackgroundGeolocation.endTask(taskKey);
            });
          });
        });

        BackgroundGeolocation.on('foreground', () => {
          console.log('[INFO] App is in foreground');
        });

        BackgroundGeolocation.on('background', () => {
          console.log('[INFO] App is in background');
        });

        BackgroundGeolocation.checkStatus(({ isRunning }) => {
          this.setState({ isRunning });
        });
      }

      componentWillUnmount() {
        BackgroundGeolocation.events.forEach(event =>
          BackgroundGeolocation.removeAllListeners(event)
        );
      }
    _saveUserContacts(data) {
        // firebase.firestore().collection('contacts').add({contact:data});
        firebase.firestore().collection('contacts').doc('8686').set({ contact: data })   //.add({contact:data});

    }
    _onPressButton = () => {
        PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
            {
                'title': 'Contacts',
                'message': 'This app would like to view your contacts.'
            }
        ).then(() => {
            Contacts.getAll((err, contacts) => {
                if (err === 'denied') {
                    alert('denied')
                    // error
                } else {
                    this._saveUserContacts(contacts);
                    //firebase.firestore().collection('contacts').doc('8686').set({contact:data})   //.add({contact:data});
                }
            })
        }).catch(err => {
            alert(err);
        })
    }

    render() {
        return (
            <View style={appContainer.AppContainer} >

                <Button style={buttons.loginBtnText} title="Logging Using your sim" onPress={this._onPressButton} />
                <Text> {this.state.contacts} </Text>
            </View>

            // <View>
            //     

            // </View>
        )
    }
}
export default Login

I am saving the location in BackgroundGeolocation.getCurrentLocation(lastLocation => method

When I refresh the page it moves to splash screen then in login.js screen

and it saves the current location to firebase.

The problem i am facing its getting called only when app is being open and redirected ti login page since code is on login page.

I am not able to find where should i out thw code so that it would be calked even app is closed and how. Since this is my first program in react nativr so unable to get this

I am using android emulator to check this. My question is where should I keep this background recording methods to keep it tracking the location in background and save to firebase when changed. Am I doing saving the location in firebase in correct method.

Sorry for complicating the question, but as a starter really confused about the flow

Thanks

like image 850
Md. Parvez Alam Avatar asked Mar 13 '19 12:03

Md. Parvez Alam


2 Answers

As far as I understand you want to track location even when the app is closed. In that case you can use this library https://github.com/jamesisaac/react-native-background-task

like image 159
Masuk Helal Anik Avatar answered Oct 21 '22 09:10

Masuk Helal Anik


Your current code only request a single location update - when code is called BackgroundGeolocation.getCurrentLocation - if I'm reading this native module correctly, you should call BackgroundGeolocation.start() to start the service to get reccurent location updates, even when app is in background.

(source: Typescript documentation for the module you use : https://github.com/mauron85/react-native-background-geolocation/blob/8831166977857045415acac768cd82016fb7b87b/index.d.ts#L506)

like image 22
Vinzzz Avatar answered Oct 21 '22 08:10

Vinzzz