transistorsoft / flutter_background_geolocation

Sophisticated, battery-conscious background-geolocation & geofencing with motion-detection
https://www.transistorsoft.com/shop/products/flutter-background-geolocation
Other
650 stars 241 forks source link

MissingPluginException(No implementation found for method listen on channel com.transistorsoft/flutter_background_fetch/events). Error thrown . #1349

Closed siddharthadevops closed 2 months ago

siddharthadevops commented 3 months ago

Your Environment

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) • Android SDK at /Users/siddhartha/Library/Android/sdk • Platform android-34, build-tools 34.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 15F31d • CocoaPods version 1.15.2

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2023.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)

[✓] IntelliJ IDEA Community Edition (version 2024.2.0.1) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin version 81.1.3 • Dart plugin version 242.20629

[✓] VS Code (version 1.92.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.94.0

[✓] Connected device (8 available) • Pixel 6a (mobile) • 29261JEGR09487 • android-arm64 • Android 14 (API 34) • CPH2161 (mobile) • NF6HPBY98LXGHM99 • android-arm64 • Android 12 (API 31) • iPhone de Dante (mobile) • 00008120-00062D983CC0C01E • ios • iOS 18.0 22A5338b • iPhone de Amir (mobile) • 00008101-000C48402881401E • ios • iOS 17.6.1 21G93 • iPhone 15 Pro Max (mobile) • 905EEE9E-8306-4379-9F60-3E96872FC350 • ios • com.apple.CoreSimulator.SimRuntime.iOS-17-4 (simulator) • macOS (desktop) • macos • darwin-arm64 • macOS 14.6.1 23G93 darwin-arm64 • Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin • macOS 14.6.1 23G93 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 127.0.6533.120 ! Error: Browsing on the local area network for iPhone 14 de Ryo . Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac. The device must be opted into Developer Mode to connect wirelessly. (code -27) ! Error: Browsing on the local area network for Apple Watch de Amir. Ensure the device is unlocked and discoverable via Bluetooth. (code -27)

[✓] Network resources • All expected network resources are available.


* Plugin config:
```dart <-- Syntax highlighting: DO NOT REMOVE -->
  Future<void> _configurePlugin(
      {required bool highPerformance, required bool configWithReady}) async {
    const debug = kDebugMode && false;

    final backgroundRationale = bg.PermissionRationale(
      title: Str.backgroundLocationAccess,
      message: Str.weNeedYourBackgroundLocationPublic,
      positiveAction: Str.openSettings,
      negativeAction: Str.cancel,
    );
    const heartBeatInterval = 3600 * 8;
    var config = Platform.isIOS
        ? bg.Config(
            reset: true,
            desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
            disableLocationAuthorizationAlert: true,
            showsBackgroundLocationIndicator: false,
            distanceFilter: _desiredAccuracy,
            preventSuspend: highPerformance,
            heartbeatInterval: heartBeatInterval,
            startOnBoot: true,
            stopOnTerminate: false,
            allowIdenticalLocations: false,
            debug: debug,
            logLevel: debug ? bg.Config.LOG_LEVEL_DEBUG : bg.Config.LOG_LEVEL_OFF,
            stopTimeout: 2,
            backgroundPermissionRationale: backgroundRationale,
          )
        // Android
        : bg.Config(
            enableHeadless: true,
            reset: true,
            desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
            showsBackgroundLocationIndicator: false,
            disableLocationAuthorizationAlert: true,
            distanceFilter: _desiredAccuracy,
            preventSuspend: highPerformance,
            heartbeatInterval: heartBeatInterval,
            stopOnTerminate: false,
            startOnBoot: true,
            debug: debug,
            allowIdenticalLocations: false,
            logLevel: debug ? bg.Config.LOG_LEVEL_DEBUG : bg.Config.LOG_LEVEL_OFF,
            stopTimeout: 2,
            backgroundPermissionRationale: backgroundRationale,
          );

    if (configWithReady) {
      _state = await bg.BackgroundGeolocation.ready(config);
    } else {
      _state = await bg.BackgroundGeolocation.reset(config);
    }

    Log.info('📍BACKGROUND-LOCATION -> Plugin configured with result:\n'
        '$_state\n'
        'configWithReady: $configWithReady\n'
        'highPerformance: $highPerformance\n'
        'enableHeadless: ${config.enableHeadless}\n');
  }

Expected Behavior

Exception should not occur

Actual Behavior

An exception occurs

Steps to Reproduce

  1. No steps to reproduce

Context

I am registering errors with this exception in Firebase Crashlytics on most Android devices. The package is working correctly, that is, even though this exception is occurring, calls are being received correctly with updates to the location, timer, etc.

So far I have not managed to reproduce this exception in my development environment, I only have the information from Crashlytics.

Analyzing the App logs of users experiencing this exception, I have found that it occurs when a notification arrives while the App has been closed by the OS.

When a notification arrives while the App is closed in my app the following happens: 1.- The isolate that received the notification creates a working isolate. 2.- The main() function is called from the main isolate.

When the working isolate is started I am calling DartPluginRegistrant.ensureInitialized();

This exception is occurring even on users who called stop() and have not called ready() or start() again.

Debug logs

Logs ``` Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: MissingPluginException(No implementation found for method listen on channel com.transistorsoft/flutter_background_fetch/events). Error thrown . at MethodChannel._invokeMethod(platform_channel.dart:332) at EventChannel.receiveBroadcastStream.(platform_channel.dart:676) ```
christocracy commented 3 months ago

No implementation found for method listen on channel com.transistorsoft/flutter_background_fetch/events

You’re receiving an error related to background_fetch but not providing any code where you’re interacting with that plugin. This is not an error from background_geolocation.

siddharthadevops commented 3 months ago

Sorry, I pasted the wrong exception. Crashlytics is grouping the two exceptions in the same group.

 Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: MissingPluginException(No implementation found for method listen on channel com.transistorsoft/flutter_background_geolocation/events/providerchange). Error thrown .
       at MethodChannel._invokeMethod(platform_channel.dart:332)
       at EventChannel.receiveBroadcastStream.<fn>(platform_channel.dart:676)

Anyway, I've solved the problem, although I don't quite know how. On the one hand, I am now calling ready() instead of setConfig() + start(). On the other hand, I am not calling ready() until I make sure that the lifecycle state is not detached. In certain circumstances the main function of the main isolate is called in this state (without the associated view)

christocracy commented 3 months ago

You MUST call .ready(config) each and every time your app launches in foreground. Calling .ready does not imply you must immediately call .start().

You do NOT call .ready(config) in the headless state.

christocracy commented 3 months ago

The plugin is not "ready" to use until .ready(config) is called. That's why the name of the method is called "ready".

siddharthadevops commented 2 months ago

After doing several tests I have verified that the exception occurs if ready() is called while the AppLifecycle is detached.

In my case, this problem arose when adding the just_audio_background package, which causes when the entry-point of notification or headless functions of this package are called, the main isolate is started and the main() function is called with a value of AppLifecycle detached.

After adding a wait until the state is other than detached (inactive, resume, etc) before calling ready(), the problem has been solved.