Please provide the following:
- SDK Version: 38
- Platforms(Android/iOS/web/all): iOS (standalone)
I have the following test code running in an app published to TestFlight (where the Firebase configs are appropriately populated and DataAgent refers to a working class that can update a Firebase database):
import * as Location from 'expo-location';
import * as BackgroundFetch from 'expo-background-fetch';
import Constants from "expo-constants";
import DataAgent from "./data/DataAgent";
import * as firebase from "firebase";
const LOCATION_TASK_NAME = 'background-location-task';
const FETCH_TASK_NAME = "fetch-task"
export default class Component extends React.Component {
onPress = async () => {
await BackgroundFetch.registerTaskAsync(FETCH_TASK_NAME);
const { status } = await Location.requestPermissionsAsync();
console.log(status);
if (status === 'granted') {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Highest,
});
}
alert("done");
};
render() {
return (
<TouchableOpacity onPress={this.onPress} style={{flex: 1, height: "100%", width: "100%", justifyContent: 'center', alignItems: 'center'}}>
<Text>Enable background location</Text>
</TouchableOpacity>
);
}
}
TaskManager.defineTask(FETCH_TASK_NAME, () => {
setTimeout(() => {
return BackgroundFetch.Result.NewData;
}, 28 * 1000)
try {
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: "",
authDomain: "",
databaseURL: "",
storageBucket: ""
});
}
const dataAgent = new DataAgent();
if (Constants.isHeadless) {
dataAgent.logBackgroundLocation({
message: "FETCHED",
isHeadless: Constants.isHeadless,
isProduction: !__DEV__
});
Location.getCurrentPositionAsync({}).then((location) => {
let lat = location.coords.latitude;
let long = location.coords.longitude;
let newUserLocation = {
latitude: lat,
longitude: long
}
console.log("App: updated current location")
dataAgent.logBackgroundLocation({
message: "LOCATION",
location: newUserLocation,
isHeadless: Constants.isHeadless,
isProduction: !__DEV__
});
}).catch((err) => {
dataAgent.logBackgroundLocation({
message: "ERROR: " + err,
isHeadless: Constants.isHeadless,
isProduction: !__DEV__
});
}).finally(() => {
})
}
} catch (error) {
}
});
TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: "",
authDomain: "",
databaseURL: "",
storageBucket: ""
});
}
const dataAgent = new DataAgent();
if (Constants.isHeadless) {
dataAgent.logBackgroundLocation({
message: "Initial",
isHeadless: Constants.isHeadless,
isProduction: !__DEV__
});
if (error) {
dataAgent.logBackgroundLocation({
message: "Error: " + error,
isHeadless: Constants.isHeadless,
isProduction: !__DEV__
});
// Error occurred - check `error.message` for more details.
console.log(error);
return;
}
if (data) {
const { locations } = data;
console.log(locations);
dataAgent.logBackgroundLocation({
message: "Locations",
locations: [locations[0].coords.latitude, locations[0].coords.longitude],
isHeadless: Constants.isHeadless,
isProduction: !__DEV__
});
// do something with the locations captured in the background
}
}
});
Without the restriction of Constants.isHeadless, this code would successfully update my database when the app was in the foreground or background (not terminated). However, the code did not work when the app was terminated (swiped up from the task manager), and after adding the restriction of Constants.isHeadless, it does not update the database at all. This leads me to think that the app is never being launched in headless mode. Here is my app.json:
{
"expo": {
"name": "something",
"slug": "something",
"version": "1.0.1",
"orientation": "portrait",
"icon": "./assets/icon.png",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": false,
"infoPlist": {
"UIBackgroundModes": [
"location",
"fetch"
],
"NSLocationWhenInUseUsageDescription": "something",
"NSLocationAlwaysAndWhenInUseUsageDescription": "something",
"NSLocationAlwaysUsageDescription": "something"
},
"bundleIdentifier": "something"
},
"android": {
"package": "something",
"permissions": [
"ACCESS_COARSE_LOCATION",
"ACCESS_FINE_LOCATION"
]
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
Has anyone had success in using background location tracking (or background fetch) in a terminated state on a standalone app with Expo SDK 38? Should I try downgrading my Expo SDK version or ejecting?
Any help would be greatly appreciated. Thank you for your time.