flutter_workmanager
flutter_workmanager copied to clipboard
🐞 Workmanager not working with path_provider on iOS background fetch (MissingPluginException(No implementation found for method getTemporaryDirectory on channel plugins.flutter.io/path_provider))
- [x] I have read the README
- [x] I have done the setup for Android
- [x] I have done the setup for iOS
- [x] I have ran the sample app and it does not work there
Version
| Technology | Version |
|---|---|
| Workmanager version | 0.4.1 |
| Xcode version | 13.2.1 |
| Swift version | 5 |
| iOS deployment target | 10 |
Describe the error
Trying to use path_provider with workmanager on iOS.
In my mainframe I can inject and use the path_provider, but when I trigger it from workmanager it wont work at all. Already tried flutter clean/get, flutter pub cache repair, close and reopen emulator and IDE..nothing works.
Here is a minimum code to reproduce: link
1 - created new flutter project
2 - added packages workamanager/path_provider
3 - initialized workmanager and setup iOS especific configuration
4 - opened xcode, ran the project then selected debug>simulate background fetch
5 - expected to see successful return with path created, but actually see MissingPluginException(No implementation found for method getTemporaryDirectory on channel plugins.flutter.io/path_provider)
Output of flutter doctor -v
[✓] Flutter (Channel stable, 2.10.2, on macOS 12.1 21C52 darwin-arm, locale en-BR)
• Flutter version 2.10.2 at /Users/brunoandrade/Dev/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 097d3313d8 (2 weeks ago), 2022-02-18 19:33:08 -0600
• Engine revision a83ed0e5e3
• Dart version 2.16.1
• DevTools version 2.9.2
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/brunoandrade/Library/Android/sdk • Platform android-31, build-tools 31.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165) ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.11.2
[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3) • 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 11.0.10+0-b96-7281165)
[✓] VS Code (version 1.65.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.36.0
Check comment https://github.com/fluttercommunity/flutter_workmanager/issues/360#issuecomment-1043171712 You can do the same workaround with path provider, till flutter and dart team fixes the actual issue 98591 in flutter repo. Add in your pubspec.yaml:
path_provider_android: ^2.0.12 path_provider_ios: ^2.0.8
Add in your workmanager callback:
if (Platform.isAndroid) PathProviderAndroid.registerWith(); if (Platform.isIOS) PathProviderIOS.registerWith();
Check comment #360 (comment) You can do the same workaround with path provider, till flutter and dart team fixes the actual issue 98591 in flutter repo. Add in your pubspec.yaml:
path_provider_android: ^2.0.12 path_provider_ios: ^2.0.8
Add in your workmanager callback:
if (Platform.isAndroid) PathProviderAndroid.registerWith(); if (Platform.isIOS) PathProviderIOS.registerWith();
It did work for me! Thank you very much. Where should it be put by default so user does not need to do it manually? On path_provider package?
I can't make it work on iOS. On Android everything is fine but on iOS I always get the following error:
MissingPluginException(No implementation found for method getApplicationDocumentsDirectory on channel plugins.flutter.io/path_provider_ios)<…>
Here is what I use:
In my pubspec.yaml
path_provider: ^2.0.9
path_provider_android: ^2.0.12
path_provider_ios: ^2.0.8
workmanager: ^0.5.0-dev.8
import 'package:path_provider_android/path_provider_android.dart';
import 'package:path_provider_ios/path_provider_ios.dart';
void callbackDispatcher() {
if (Platform.isAndroid) PathProviderAndroid.registerWith();
if (Platform.isIOS) PathProviderIOS.registerWith();
Workmanager().executeTask((task, inputData) async {
Logger().d("Native called background task");
try {
var dir = await getApplicationDocumentsDirectory(); // <-- NEVER PASSES AFTER THIS LINE.
Logger().d("dir=${dir.path}");
} on Exception catch(error){
Logger().e(error);
}
return Future.value(true);
});
}
Workmanager initialization:
Workmanager().initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode: false // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
);
What am I doing wrong, because
if (Platform.isAndroid) PathProviderAndroid.registerWith();
if (Platform.isIOS) PathProviderIOS.registerWith();
does NOT seem to work?
@sirmamedical, if you try with getTemporaryDirectory() instead of getApplicationDocumentsDirectory(), you get same results? Did you finish and started application instead of hot reload? Did you run flutter clean / flutter pub get after change?
@brunodmn I haven't tried with getTemporaryDirectory() because I need getApplicationDocumentsDirectory() in order to use Drift plugin from the background task and the initial issue happened when I called a db query.
I checked then that a simple call of getApplicationDocumentsDirectory() without any db usage causes the same error.
I did flutter clean and flutter pub get many times. I tested the app on a real device using the Simulate background fetch from XCode debug.
I will check what will be behaviour when I use getTemporaryDirectory() instead, in the background, although even it will work it will not solve my problem with Drift, because it needs getApplicationDocumentsDirectory(). I will let you know what the result is.
Hi @sirmamedical, if works with temporary directory might be something with permission to access files on device, which you could try to ask permission on first run, before initializing the Workmanager. I noticed that you are using a pre-release version, you could also try with published stable version of the package. I hope you can make it work
I have the same issue when trying to work with hive any workaround. and @brunodmn did you get any solution I have been working on this for two days
I have the same issue when trying to work with hive any workaround. and @brunodmn did you get any solution I have been working on this for two days
Hi Brian,
With hive you could try #360.
- Add packages path_provider_android and path_provider_ios
- Add bellow snipet into your callbackdispatcher (before initializing hive):
if (Platform.isAndroid) PathProviderAndroid.registerWith();
if (Platform.isIOS) PathProviderIOS.registerWith();
Can you please try this branch / PR https://github.com/fluttercommunity/flutter_workmanager/pull/388 and let me know whether it solves the problem?
for me it looks like the problem still exists.
void uploadUserData() {
if (Platform.isAndroid) PathProviderAndroid.registerWith();
if (Platform.isIOS) PathProviderIOS.registerWith();
Workmanager().executeTask((task, inputData) async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
MyRepository().syncUploadFiles();
}
@ened I tried that branch and doesn't seem to fix the issue. Tested another plugin that implements the DartPluginRegistrant.ensureInitialized() method and it seems to work. This is the plugin: https://pub.dev/packages/flutter_background_service
Maybe it helps you realize what works incorrectly here. I also tried to call those methods by myself and still it doesn't work
Please retry using the latest version 0.5.1