Closed fixatd closed 1 year ago
Post your entire lib/main.dart
@christocracy here is the content of lib/main.dart
.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:uk_power_mobile/features/init/init.dart';
import 'package:uk_power_mobile/features/routes.dart';
import 'package:uk_power_mobile/firebase_options.dart';
import 'package:uk_power_mobile/locator.dart';
import 'package:uk_power_mobile/logger.dart';
import 'package:uk_power_mobile/navigator_plus.dart';
import 'package:background_fetch/background_fetch.dart';
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart'
as bg;
import 'package:uk_power_mobile/services/location.dart';
import 'package:uk_power_mobile/services/messaging.dart';
import 'package:uk_power_mobile/ui/colors.dart';
import 'package:uk_power_mobile/ui/widgets/app_builder.dart';
@pragma('vm:entry-point')
void headlessLocationEventHandler(bg.HeadlessEvent headlessEvent) async {
InternalLogger.debug('[BackgroundGeolocation HeadlessTask]: $headlessEvent');
switch (headlessEvent.name) {
case bg.Event.HEARTBEAT:
bg.HeartbeatEvent event = headlessEvent.event;
InternalLogger.debug("onHeartbeat detected: $event");
InternalLogger.debug("Trying to fetch current location");
bg.Location location = await bg.BackgroundGeolocation.getCurrentPosition(
timeout: 60, samples: 1, maximumAge: 2000);
InternalLogger.debug('Returned location: $location');
break;
case bg.Event.LOCATION:
bg.Location location = headlessEvent.event;
InternalLogger.debug("onLocation detected: $location");
break;
case bg.Event.CONNECTIVITYCHANGE:
bg.ConnectivityChangeEvent event = headlessEvent.event;
InternalLogger.debug("onConnectivityChange detected: $event");
if (event.connected) {
InternalLogger.debug("Device is connected, triggering sync");
}
break;
}
}
@pragma('vm:entry-point')
void backgroundFetchHandler(HeadlessTask task) async {
String taskId = task.taskId;
InternalLogger.debug('Background task event received, $taskId');
switch (taskId) {
case offDutyStopTaskId:
InternalLogger.debug("Trying to start BackgroundGeolocation");
bg.BackgroundGeolocation.state.then((state) {
InternalLogger.debug("Config change ready: $state");
if (!state.enabled) {
InternalLogger.debug(
"BackgroundGeolocation is not enabled, trying to start");
bg.BackgroundGeolocation.start();
}
});
break;
case offDutyStartTaskId:
InternalLogger.debug("Stopping location tracking");
bg.BackgroundGeolocation.stop();
break;
}
BackgroundFetch.finish(taskId);
}
Future<void> main() async {
InternalLogger.debug("Starting application");
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
InternalLogger.debug("Showing splash screen");
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
InternalLogger.debug("Initialising firebase");
FirebaseApp firebaseApp = await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
InternalLogger.debug("Firebase App: ${firebaseApp.name}");
setupCrashlytics();
FirebaseFirestore.instance.settings = const Settings(
persistenceEnabled: true,
cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED,
);
setupLocator();
InternalLogger.debug("Setting up messaging service");
locator<MessagingService>().init();
InternalLogger.debug("Setting up background geolocation headless tasks");
bg.BackgroundGeolocation.registerHeadlessTask(headlessLocationEventHandler);
BackgroundFetch.registerHeadlessTask(backgroundFetchHandler);
runApp(const ProviderScope(child: UkPowerApp()));
}
void setupCrashlytics() {
InternalLogger.debug("Setting up crashlytics");
FlutterError.onError = (errorDetails) {
FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
};
}
class UkPowerApp extends StatefulWidget {
const UkPowerApp({Key? key}) : super(key: key);
@override
UkPowerAppState createState() => UkPowerAppState();
}
class UkPowerAppState extends State<UkPowerApp> {
@override
Widget build(BuildContext context) {
return AppBuilder(
builder: (context) {
return MaterialApp(
navigatorKey: navigatorPlus.key,
debugShowCheckedModeBanner: false,
routes: routes,
theme: theme(),
initialRoute: InitScreen.routeName,
);
},
);
}
}
See here
I'll give it a try, should I just call it directly from main()
or would it make sense to also add it to the BackgroundFetch headless task handler (backgroundFetchHandler
).
I'm still getting the error even after adding DartPluginRegistrant.ensureInitialized()
at main
. I'm wondering if there is a way to call this on boot since it doesn't seem to be getting initialised correctly even at main
.
A bit of a late reply but I've managed to find what was causing the issue. I had included this code snippet as per the firebase documentation:
FirebaseFirestore.instance.settings = const Settings(
persistenceEnabled: true,
cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED,
);
And taking it out seems to have fixed everything.
Your Environment
1.0.0
flutter info
,flutter doctor
):pubspec.yaml
To Reproduce Steps to reproduce the behavior:
BackgroundFetch
library that restarts location tracking after a certain amount of time i.e.5 mins
;BackgroundGeolocation
to restart location tracking;Firestore
no longer works;Debug logs
Additional context
We have a feature on our application that allows the user to turn off their location tracking for a certain amount of time, the restart mechanism itself uses
BackgroundFetch
and works just fine. The issue happens when we reboot the device, just for context most of the users we have will turn off the device after turning off location tracking since they're conscious about being tracked and they will turn on the device once they know they have to be tracked again.After a bit of debugging, I noticed that we weren't getting the issue when we don't have
background_geolocation_firebase
installed which points to a conflict with how firestore is being initialised after the reboot and subsequent re-initialisation of the application.Also as a side note, the location tracking and firestore location sync works just fine when the application UI isn't brought to the foreground.
Let me know if you need anymore logs or info from our end, wasn't sure what you'd need so I've added just the obvious ones.