Flutter: how do I write a file to local directory with path_provider?
339
Here's an example of the data uri method mentioned in the comments:
import 'dart:html' as html;
final bytes = utf8.encode('hello!');
final dataUri = 'data:text/plain;base64,${base64.encode(bytes)}';
html.document.createElement('a') as html.AnchorElement
..href = dataUri
..download = 'my_file.txt'
..dispatchEvent(html.Event.eventType('MouseEvent', 'click'));
Make sure that's in a dart file that's only imported when html
is available, or preferably, use package:universal_html
.
Author by
Emile Haas
Updated on January 04, 2023Comments
-
Emile Haas over 1 year
I'm working on a Flutter app and need to write files to the local system (iOS, Android but also Web). I have logically followed the documentation on Read and Write Files, and used
path_provider
to make a small example to test functionality:import 'package:path_provider/path_provider.dart'; ... void _testPathProvider() async { // Directory appDocDir = await getTemporaryDirectory(); // Using a different dir. not working either // String appDocPath = appDocDir.path; Directory appDocDir = await getApplicationDocumentsDirectory(); String appDocPath = appDocDir.path; debugPrint('$appDocPath/my_file.txt'); // Save in local file system var file = await File('$appDocPath/my_file.txt').writeAsString('hello!'); }
This test function is simply called by a button, nothing crazy there. But when I run flutter in browser & press button, I get following error:
Error: MissingPluginException(No implementation found for method getApplicationDocumentsDirectory on channel plugins.flutter.io/path_provider) at Object.throw_ [as throw] (http://localhost:42561/dart_sdk.js:5067:11) at MethodChannel._invokeMethod (http://localhost:42561/packages/flutter/src/services/restoration.dart.lib.js:1560:21) at _invokeMethod.next (<anonymous>) at http://localhost:42561/dart_sdk.js:40571:33 at _RootZone.runUnary (http://localhost:42561/dart_sdk.js:40441:59) at _FutureListener.thenAwait.handleValue (http://localhost:42561/dart_sdk.js:35363:29) at handleValueCallback (http://localhost:42561/dart_sdk.js:35931:49) at Function._propagateToListeners (http://localhost:42561/dart_sdk.js:35969:17) at _Future.new.[_completeWithValue] (http://localhost:42561/dart_sdk.js:35817:23) at async._AsyncCallbackEntry.new.callback (http://localhost:42561/dart_sdk.js:35838:35) at Object._microtaskLoop (http://localhost:42561/dart_sdk.js:40708:13) at _startMicrotaskLoop (http://localhost:42561/dart_sdk.js:40714:13) at http://localhost:42561/dart_sdk.js:36191:9
Seems like the issue is well-know, have followed advice both here and here, including :
- running
flutter clean
and re-getting packages - closing app completely and re-running
- upgrading Flutter to latest stable
- re-adding
path_provider
to my pubspec.yaml
I'm using latest version of the dependency (
path_provider: ^2.0.9
).Any help much appreciated.
-
Richard Heap about 2 yearsWeb applications run in browsers, and browsers can't write to arbitrary locations on disk, so
path_provider
isn't supported on Flutter web. -
Richard Heap about 2 yearsOne solution is to create a data uri with the contents, behind an anchor tag and then programmatically click it - browser will then offer to 'download' the contents.
-
Emile Haas about 2 yearsThanks a lot for the interest. I was confused about it as the package doc says
getApplicationDocumentsDirectory
is supported on Linux, but I guess they meant Linux app. If you have an example of usign the URI strategy on Flutter, highly appreciated. Also, would this strategy work for iOS and Android too (to download file on phone storage?). -
Richard Heap about 2 yearsNo, won't work on iOS etc. Use the 'normal' way for that.
- running