flutter_background_service icon indicating copy to clipboard operation
flutter_background_service copied to clipboard

MissingPluginException when using external plugins (SharedPreferences, PathProvider, etc)

Open ekasetiawans opened this issue 2 years ago • 22 comments

When we use external plugin in background service, MissingPluginException will be thrown. This happens because the plugin we are using is not registered in the background service isolate (flutter engine) yet. To avoiding it, we have workaround below:

For Flutter prior to version 3.0.0, we have to call this code depending what plugins you use.

void onStart(ServiceInstance service){
  ...
  if (Platform.isIOS) YourPluginIOS.registerWith();
  if (Platform.isAndroid) YourPluginAndroid.registerWith();
  ...
}

For Flutter version 3.0.0 and later, there is generated class to register all of plugins. So we can call like this

void onStart(ServiceInstance service){
  ...
  DartPluginRegistrant.ensureInitialized();
  ...
}

ekasetiawans avatar Apr 21 '22 13:04 ekasetiawans

@ZiaUrRahmam sorry for unclear information, you have to replace YourPluginAndroid or YourPluginIOS with the plugin you using.

ekasetiawans avatar Apr 24 '22 09:04 ekasetiawans

i faced the same issue as well but with GetStorage & i tried using shared preferences but i kept on getting an exception. otherwise this is a great plugin and it so unfortunate that i could not preform what i wanted.

ReggieMiller1 avatar Apr 24 '22 20:04 ReggieMiller1

@ReggieMiller1 the easiest way is try to use flutter beta channel. So, you will not be confused to register the plugins because you only need to call DartPluginRegistrant.ensureInitialized()

ekasetiawans avatar Apr 24 '22 20:04 ekasetiawans

@ReggieMiller1 the easiest way is try to use flutter beta channel. So, you will not be confused to register the plugins because you only need to call DartPluginRegistrant.ensureInitialized()

alright i get you bro but please give me an example on how to do it DartPluginRegistrant.ensureInitialized()

ReggieMiller1 avatar Apr 24 '22 21:04 ReggieMiller1

@ReggieMiller1 I already mentioned it at the top of this page. You should to call the method in void onStart(ServiceInstance service) method that used by FlutterBackgroundService.configure.

ekasetiawans avatar Apr 24 '22 21:04 ekasetiawans

@ReggieMiller1 I already mentioned it at the top of this page. You should to call the method in void onStart(ServiceInstance service) method that used by FlutterBackgroundService.configure.

thanks bro...i did what you said, at first i didnt understand but now everything works fine. thanks once again.

ReggieMiller1 avatar Apr 25 '22 07:04 ReggieMiller1

@ekasetiawans I tried the above solution, but other error occur. 2022-05-06 11:43:44.376688+0800 Runner[40780:421791] [VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)

Flutter version: Flutter 2.13.0-0.3.pre • channel beta • https://github.com/flutter/flutter.git Framework • revision 5293f3cd44 (8 days ago) • 2022-04-27 12:37:50 -0700 Engine • revision 3096903c89 Tools • Dart 2.17.0 (build 2.17.0-266.7.beta) • DevTools 2.12.2

lel101 avatar May 06 '22 03:05 lel101

btw it happens when socket IO is inside the flutter_background_service and SharedPreferences.getInstance() is called when have a coming notifications.

Future onStart(ServiceInstance service) async {
DartPluginRegistrant.ensureInitialized();

socket?.on('receive-notify-user', (data) async {//If this socket is triggered SharedPreferences pref = await SharedPreferences.getInstance();// Error occur here. });

lel101 avatar May 06 '22 03:05 lel101

@ekasetiawans any updates ? Please can you help me with this ?

lel101 avatar May 10 '22 02:05 lel101

What do you mean by this :

void onStart(ServiceInstance service){ ... if (Platform.isIOS) YourPluginIOS.registerWith(); if (Platform.isAndroid) YourPluginAndroid.registerWith(); ... }

I tried to replace "YourPluginIOS" and "YourPluginAndroid" by Shared prefe (for example), but the method registerWith() is not defined with any plugin.

hassanali2596 avatar May 17 '22 16:05 hassanali2596

@hassanali2596 You have to add https://pub.dev/packages/shared_preferences_ios and https://pub.dev/packages/shared_preferences_android depending to your target platform.

If you already using flutter 3, you can call DartPluginRegistrant.ensureInitialized() instead, it will register our plugins automatically.

ekasetiawans avatar May 18 '22 00:05 ekasetiawans

@ekasetiawans I already upgrade my flutter to 3 and still having issue.

[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)

lel101 avatar May 18 '22 03:05 lel101

@lel101 that is different issue

ekasetiawans avatar May 18 '22 03:05 ekasetiawans

@ekasetiawans ahh I see thanks, is there any fix or workaround for this issue ?

Sorry, Am I the only one having this error after applying this workaround(DartPluginRegistrant.ensureInitialized()) ?

lel101 avatar May 18 '22 03:05 lel101

@lel101 you have to make sure which plugin that throws the error

ekasetiawans avatar May 18 '22 03:05 ekasetiawans

@ekasetiawans

It throws error in SharedPreferences.getInstance();

Before the error was MissingPluginException but after the flutter upgrade to 3 and added the line DartPluginRegistrant.ensureInitialized(); the error change to PlatformException.

Future<void> onStart(ServiceInstance service) async {
    DartPluginRegistrant.ensureInitialized();
    SharedPreferences pref = await SharedPreferences.getInstance();
}

lel101 avatar May 18 '22 04:05 lel101

@lel101 which platform are you targeting? iOS or Android?

ekasetiawans avatar May 18 '22 04:05 ekasetiawans

@ekasetiawans IOS

lel101 avatar May 18 '22 04:05 lel101

@lel101 okay, I will check it after work

ekasetiawans avatar May 18 '22 04:05 ekasetiawans

hi everyone, sorry for late I have published the version 2.1.0.

@lel101 your issue is caused by the plugins not being registered in the iOS native side. I have update the version 2.1.0 to remove requirement for it, so I think it will be resolved once you update the dependency version.

ekasetiawans avatar May 19 '22 06:05 ekasetiawans

@ekasetiawans I already test it and now it works fine. Thank you so much.

lel101 avatar May 19 '22 07:05 lel101

What if the plugin dont have registerWith() ? try DartPluginRegistrant.ensureInitialized(); with no luck, only work when app forground, background, not work when app is killed

nguyenphuc1995 avatar Jun 07 '22 04:06 nguyenphuc1995

Hi, I'm using record (https://pub.dev/packages/record). I tried DartPluginRegistrant.ensureInitialized(), and it doesn't has registerWith() for Android/iOS Please help.

The exception: E/flutter ( 9952): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method start on channel com.llfbandit.record/messages)

The package's code of v4.4.4: https://github.com/llfbandit/record/tree/404505e308d21cf7f0dc5ec180b213f7c26d3dd7

vietstone-ng avatar Aug 04 '23 18:08 vietstone-ng

@nguyenphuc1995 Did you find a way to overcome the problem?

vietstone-ng avatar Aug 10 '23 09:08 vietstone-ng