tekartik / sqflite

SQLite flutter plugin
BSD 2-Clause "Simplified" License
2.86k stars 521 forks source link

iOS: can not open db within isolate using workmanager and floor plugins #1078

Closed andresc-dev closed 8 months ago

andresc-dev commented 8 months ago

I developed an app in Flutter using workmanager plugin and the DB service uses Floor, a layer on top of sqflite. It does CRUD operations on main isolate and has a background job every 30 minutes to sync the db against a cloud service in the workmanager isolate.

It works well on Android. On Android I simply do final db = await $FloorAppDatabase.databaseBuilder('database.db').build();

Same sentence in iOS fails with MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite) Which is a flutter interface calling a not found native method in the abstract class DatabaseFactory (file sqlite_api.dart)

Reading issues and stackoverflow posts, I finally found the work @alextekartik did on this branch but unfortunately the code is more complex than needed to show the steps to properly get the DB opened on the workmanager isolate. I was not able to fully understand the magic to make it work.

I read about the non-thread safety of opening the DB on another isolate. I need read only access, then write a boolean field indicating upload ok on cloud server.

Hope someone can point me out with a workaround. If not I need to rewrite the database service using another isolate aware framework.

Thanks much

`

andresc-dev commented 8 months ago

Follow up

I was finally able to make it work. The issue was related to the isolate having no plugins registered at all (ie: sqflite)

The solution is to add WorkmanagerPlugin.setPluginRegistrantCallback { registry in GeneratedPluginRegistrant.register(with: registry) } on ios/Runner/AppDelegate.swift file.

See this as an example. It was also documented here

Hope this writing helps others!