Search code examples
flutterflutter-dependenciesflutter-web

Flutter: how do I write a file to local directory with path_provider?


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.


Solution

  • 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.