Closed UnSket closed 4 years ago
Please provide properly formatted logs
Here it is. Sorry 189020231397890 (1).txt
Show some off your code. You're doing something weird.
Here is component, which responsible for almost all work with plugin
import BackgroundGeolocation from 'react-native-background-geolocation';
import { NativeModules } from 'react-native';
import { connect } from 'react-redux';
import React from 'react';
import pkg from '../../../package.json';
import { endpoints } from '../../sagas/api';
import {
geolocationUpdated,
geolocationError,
geolocationSent,
geolocationSendError,
geolocationEvent,
geolocationClearPositions,
} from '../../actions/geolocation';
import _ from 'lodash';
import { createSelector } from 'reselect';
class Geolocation extends React.Component {
render() {
return null;
}
async componentDidMount() {
const { dispatch, options } = this.props;
// Unsubscribe from old events
await BackgroundGeolocation.removeListeners();
// Subscribe to `location` event
// -------------------
BackgroundGeolocation.onLocation(
location => dispatch(geolocationUpdated(location.coords)), // (!) use 'location.coords', not 'location'
error => dispatch(geolocationError(error)),
);
// Post events to AppMetrica for debugging
// ---------------------------------------
BackgroundGeolocation.onHttp(http => {
if (http.success) {
dispatch(geolocationSent(http));
} else {
dispatch(geolocationSendError(http));
// clear locations if have bad data
if (http.status === 422) {
BackgroundGeolocation.destroyLocations();
dispatch(geolocationClearPositions());
}
}
});
// event = { isMoving: true, location } - Device just started moving
// event = { isMoving: false, location } - Device just stopped
BackgroundGeolocation.onMotionChange(event => {
dispatch(geolocationEvent('motionchange', event));
});
// Fires every 60 seconds
BackgroundGeolocation.onHeartbeat(event => {
dispatch(geolocationEvent('heartbeat', event));
});
// Fires when internet connection becomes available / not available
BackgroundGeolocation.onConnectivityChange(event => {
dispatch(geolocationEvent('connectivitychange', event));
});
// event = { activity: 'still'|'on_foot'|'in_vehicle'|'on_bicycle'|'running', confidence: 100% }
BackgroundGeolocation.onActivityChange(event => {
dispatch(geolocationEvent('activitychange', event));
});
dispatch(geolocationEvent('1. Reset config. Initialize with new config', options));
await BackgroundGeolocation.reset(options);
try {
dispatch(geolocationEvent('2. Initialized config. Starting service'));
await BackgroundGeolocation.start();
dispatch(geolocationEvent('3. Started service. Setting pace to moving'));
await BackgroundGeolocation.changePace(true);
dispatch(geolocationEvent('4. Set pace to moving. Asking current location once'));
const location = await BackgroundGeolocation.getCurrentPosition({
maximumAge: 60 * 1000, // 1 minute
desiredAccuracy: 100, // 100 meters
samples: 1, // override default 3 samples (to choose most accurate) before firing location
persist: true, // save in SQLite (will POST to /push-positions)
});
dispatch(geolocationEvent('5. Got first location'));
dispatch(geolocationUpdated(location.coords));
} catch (error) {
dispatch(geolocationError(error));
}
}
shouldComponentUpdate(nextProps) {
return !_.isEqual(this.props.options, nextProps.options); // deep compare
}
async componentDidUpdate(prevProps) {
const { options, dispatch } = this.props;
// Sync component state with plugin state
dispatch(geolocationEvent('Pushing config update to plugin', options));
await BackgroundGeolocation.setConfig(options);
const isStarted = !prevProps.options.startOnBoot && options.startOnBoot;
if (isStarted) {
await BackgroundGeolocation.destroyLocations();
dispatch(geolocationClearPositions());
NativeModules.PinnerModule.startService(true);
}
const isStopped = !options.startOnBoot && prevProps.options.startOnBoot;
if (isStopped) {
NativeModules.PinnerModule.stopService();
}
}
}
const getSettings = state => state.settings;
const getToken = state => state.api.token;
const getRoute = state => state.routes.byID[state.routes.selected];
const getCourier = state => state.app.courier;
const getAPIVersion = state => state.api.version;
const getOptions = (settings, token, route, courier, apiVersion) => {
// token not null = phone is authorized
// courier not null = courier logged in
// route not null = courier has orders today
const enableTracking = !!(token && route && courier); // must be boolean
let endpoint = 'push-positions';
let pushPositionsV2Settings = {};
if (settings.usePushPositionsV2) {
pushPositionsV2Settings = {
enableTimestampMeta: true,
locationTemplate: '',
maxBatchSize: 10,
};
endpoint = 'push-positions-v2';
}
return {
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH, // Use GPS, WiFi and Cellular for geolocation
distanceFilter: 10, // meters to move before update event fires
fastestLocationUpdateInterval: 1000, // if another app is using location, accept updates every N ms
locationUpdateInterval: 10000, // actively request location every N ms
heartbeatInterval: 60, // Send 'heartbeat' events every 60 seconds
debug: __DEV__, // for debug sounds
logLevel: __DEV__
? BackgroundGeolocation.LOG_LEVEL_VERBOSE
: BackgroundGeolocation.LOG_LEVEL_DEBUG,
stopOnTerminate: !enableTracking, // Stop plugin when app is closed and tracking is OFF (e.g. when logged out)
startOnBoot: enableTracking, // Start on Android boot if tracking is ON
foregroundService: true, // show in notification bar, keep service alive as much as possible
notificationTitle: 'Яндекс.Курьер',
notificationText: 'Использует GPS',
maxDaysToPersist: 3,
url: enableTracking
? `${endpoints[apiVersion]}/couriers/${courier.id}/routes/${route.id}/${endpoint}`
: null,
autoSync: true,
batchSync: true,
maxBatchSize: 100, // Max locations size in request
httpRootProperty: 'positions',
locationTemplate:
'{ "accuracy": <%= accuracy %>, "latitude":<%= latitude %>, "longitude":<%= longitude %>, "time": "<%= timestamp %>" }',
headers: {
Authorization: `Auth ${token}`,
'User-Agent': `com.yandex.courier v${pkg.version}`,
},
enableHeadless: true,
...settings.geolocation, // settings to override these values
...pushPositionsV2Settings,
};
};
const optionsSelector = createSelector(
[getSettings, getToken, getRoute, getCourier, getAPIVersion],
getOptions,
);
export default connect(state => ({
options: optionsSelector(state),
}))(Geolocation);
FYI: enable multi-line syntax highlighting in markdown by wrapping code in 3 backticks, *not one**.
This looks really weird. Where are you calling #ready
?
What's the point of this?
stopOnTerminate: !enableTracking, // Stop plugin when app is closed and tracking is OFF (e.g. when logged out)
startOnBoot: enableTracking,
When you want to stop tracking, just call #stop
. There's no point modifying these params.
When a user enters the application, he is not authorized, but I want the location to be determined and displayed on the map. To do this, I run the plugin, but I set it the flag of enableTracking: false. So, if the user does not log in and exits or minimizes the application, the plugin will not work as ia m expected. When the user logs in, I set the flag true.
I do not call the ready method. Instead, I call reset and then start
if i call stop current location will not be determined
Don’t do that, it’s ugly.
Use the method getCurrentPosition
. If you want that position persisted while plugin disabled, explicitly set persist: true in the options to that method.
Read the api docs for getCurrentPosition.
Ok, but will it fix the problem?
I do not call the read method. Instead, I call reset and then start
You MUST call ready. If you don’t, bad things will happen. Especially with iOS, which won’t even work.
Thank you! it seems to have helped
Your Environment
react-native -v
): 0.59.9Expected Behavior
App will be running
Actual Behavior
App crushes
Steps to Reproduce
Debug logs
189020231397890.txt
Logs
![image](https://user-images.githubusercontent.com/31548789/72620321-1fafc000-3950-11ea-9bbb-e40399e8f016.png)