7

I am trying to access the local database on the device while the app is completely closed, to achieve this I am using the sqlite plugin sqflite: ^1.2.0 and the background fetch plugin background_fetch: ^0.4.0.

I am able to register the headless background task with no issues, its when I try to run the background tasks, I get the following error!

The plugins seems to work fine while the app is running, or put into background mode.

Any suggestions please?

Error

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)

Flutter version:

Flutter 1.12.13+hotfix.7 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 9f5ff2306b (11 days ago) • 2020-01-26 22:38:26 -0800
Engine • revision a67792536c
Tools • Dart 2.7.0

Flutter Doctor

[✓] Flutter (Channel stable, v1.12.13+hotfix.7, on Mac OS X 10.15.2 19C57, locale en-GB)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.3)
[✓] Android Studio (version 3.5)
[✓] Connected device (1 available)

• No issues found!

Billy Mahmood
  • 1,857
  • 5
  • 26
  • 37

4 Answers4

1

You can try looking at sqflite troubleshooting section on their Github page, especially the one related to your error. Let me paste the bits from that page here.

This error is typically a build/setup error after adding the dependency.

  • Try all the steps defined at the top of the documents
  • Make sure you stop the current running application if any
  • Force a flutter packages get
  • Try to clean your build folder flutter clean
  • On iOS, you can try to force a pod install / pod update
  • Search for other bugs in flutter like this, other people face the same issue with other plugins so it is likely not sqflite related

Advanced checks:

Check the GeneratedPluginRegistrant file that flutter run should have generated in your project contains a line registering the plugin.

Android:

SqflitePlugin.registerWith(registry.registrarFor("com.tekartik.sqflite.SqflitePlugin"));

iOS:

[SqflitePlugin registerWithRegistrar:[registry registrarForPlugin:@"SqflitePlugin"]];
  • Check MainActivity.java (Android) contains a call to GeneratedPluginRegistrant asking it to register itself. This call should be made from the app launch method (onCreate).
public class MainActivity extends FlutterActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);
    }
}
  • Check AppDelegate.m (iOS) contains a call to GeneratedPluginRegistrant asking it to register itself. This call should be made from the app launch method (application:didFinishLaunchingWithOptions:).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

Before raising this issue, try adding another well established plugin (the simplest being path_provider or shared_preferences) to see if you get the error here as well.

Zerocchi
  • 614
  • 1
  • 8
  • 20
0

If your case is the same as mine, I have a custom plugin with Kotlin, so I didn't import GeneratedPluginRegistrant.registerWith(this) at the MainActivity. Instead, I implemented it at the start of the configureFlutterEngine() function and it worked perfectly.

import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity : FlutterActivity() {

    private val CHANNEL = "getEpubs"
    var _eventSink: EventChannel.EventSink? = null

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
}

This registers the generated sqflite plugin access to the database on the device.

(Sorry for the Kotlin code, but you can change it to Java.)

Don't forget to import:

io.flutter.plugins.GeneratedPluginRegistrant
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Samson Ayalew
  • 359
  • 3
  • 8
0

This may be because one of the other plugins in your project is failing during plugin registration and preventing other plugins listed below it from being registered.

If you see the line below in your logs,

Tried to automatically register plugins with FlutterEngine @{engine hash appears here} but could not find and invoke the GeneratedPluginRegistrant;

set a break point in GeneratedPluginRegister's registerGeneratedPlugins() static method to see what exception is being thrown.

In my case I was using a plugin that called io.flutter.plugin.common.PluginRegistry.Registrar's activity() method which returns null when there is no foreground activity in the application.

Edwin Nyawoli
  • 836
  • 8
  • 20
-1

There has been some experiments about using sqflite from a background isolate and I'm not sure about the plugin support here. Anyway the transaction mechanism is not safe across isolate in the same process so I advise using sqflite from the main isolate (it already uses its own thread).

alextk
  • 5,713
  • 21
  • 34
  • Hi, I am trying to run my code in a headless env of the app, so this is a background service that runs every 15 mins, even if the app is closed. background fetch plugin seems to be working fine, I just can't seem to access the Database. – Billy Mahmood Feb 12 '20 at 10:13