3

I am trying to send user's location to Firestore even when the app is killed. I'm successfully able to send data to Firestore when the app is in the foreground or background but unable to send data when the app is killed. Can anyone explain what could be the problem?

I'm using

background_locator: ^1.6.4

Flutter

Flutter 2.2.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision f4abaa0735 (2 weeks ago) • 2021-07-01 12:46:11 -0700
Engine • revision 241c87ad80
Tools • Dart 2.13.4

Dart

Dart SDK version: 2.13.4 (stable) (Wed Jun 23 13:08:41 2021 +0200) on "linux_x64"

This code that I'm trying to execute once data is received

receiverPort.listen(
      (dynamic data) async {
        if (data != null) {
          WidgetsFlutterBinding.ensureInitialized();
          await Firebase.initializeApp();
          final LocationDto position = data as LocationDto;
          print('data: $position');

          final Member member = await FirebaseService().getCurrentUserProfile();
          member.currentPosition = '${position.latitude},${position.longitude}';
          await FirebaseService()
              .updateData(
                  FirebaseService.memberRef,
                  FirebaseService.memberChildId,
                  FirebaseService.getCurrentUserId(),
                  member.toJson())
              .then((value) {});
        } else {
          print('data is null');
        }
      },
    );

Please let me know if I need to share anything else. Thanks

Zeeshan Ahmad
  • 606
  • 5
  • 19

2 Answers2

1

I found the problem. I need to add Firestore code in the callback instead of in the ReceivePort. Here is the working code:

Future<void> _startLocator() async {
    final Map<String, dynamic> data = {'countInit': 1};
    return BackgroundLocator.registerLocationUpdate(
        LocationCallbackHandler.callback, // <-- You need to add your callback code here
        initCallback: LocationCallbackHandler.initCallback,
        initDataCallback: data,
        disposeCallback: LocationCallbackHandler.disposeCallback,
        iosSettings: const IOSSettings(
            accuracy: location_settings.LocationAccuracy.BALANCED,),
        androidSettings: AndroidSettings(
            accuracy: location_settings.LocationAccuracy.BALANCED,
            interval: 5,
            androidNotificationSettings: AndroidNotificationSettings(
                notificationChannelName: 'Location tracking',
                notificationTitle:
                    location.isNotEmpty ? location : 'Start Location Tracking',
                notificationMsg: 'Track location in background',
                notificationBigMsg:
                    'Background location is on to keep the app up-to-date with your location. This is required for main features to work properly when the app is not running.',
                notificationIconColor: Colors.grey,
                notificationTapCallback:
                    LocationCallbackHandler.notificationCallback)));
  }
Future<void> callback(LocationDto locationDto) async {
   // Your call back code goes here
}
Zeeshan Ahmad
  • 606
  • 5
  • 19
0

When the app's process is killed, all of its code stops executing. This includes any Firestore listeners. The OS does this in order to prevent an app from unexpectedly burning battery and data when the user isn't using it. This is a feature intended for the benefit of the end user, and your app should respect that.

See also:

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441