1

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.

Emile Haas
  • 370
  • 3
  • 14
  • 1
    Web 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 Apr 08 '22 at 13:54
  • 1
    One 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. – Richard Heap Apr 08 '22 at 14:08
  • Thanks 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?). – Emile Haas Apr 08 '22 at 14:24
  • No, won't work on iOS etc. Use the 'normal' way for that. – Richard Heap Apr 08 '22 at 16:05

1 Answers1

1

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.

Richard Heap
  • 48,344
  • 9
  • 130
  • 112