Dialogs Not Showing in Snap Package (Flutter)

I’ve built a Flutter application that works perfectly on Windows, Linux and Android. However, when I compile and run the code as a snap package, the file dialog windows do not appear.

The dialogs use the file_picker plugin (v8.1.2).

I’ve spent hours following different instructions on the internet and asked multiple different AI’s, but nothing seems to work.

This is my snapcraft.yaml file:

name: jpl
version: 0.6.0.0
summary: TBC
description: TBC.

confinement: strict
base: core22
grade: devel

apps:
  jpl:
    command: jpl
    extensions: [gnome]
    plugs:
      - dbus
      - desktop
      - home
      - system-observe
    slots:
      dbus-gtk

parts:
  jpl:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart

plugs:
  dbus:
    bus: session
    name: "org.gtk.Actions"

slots:
  dbus-gtk:
    interface: dbus
    bus: session
    name: au.com.jpl

I have also tried with desktop-legacy, but that had no effect.

There are no errors when compiling nor in snappy-debug when I run the app from the snap package.

I’ve also posted the question here.

Any advice would be greatly appreciated!

Thanks!

This project also uses file_picker.

You can give a look in the snap package. But, I believe, that’s not the case here. Are you on Ubuntu 22.04. Can you share the source code. I also have a small flutter app, but that uses file_selector and I had no problem snapping it.

1 Like

I wonder whether it is related to the file picker XDG desktop portal…

1 Like

Thanks, @soumyaDghosh. I had a look at that project, but they don’t seem to be using file_picker to display the dialogs (they are using file_selector - file_picker is being used for another purpose). I could switch to file_selector, but annoyingly, that plugin supports open dialogs on all platforms, but doesn’t support save dialogs on Android and iOS and I need both open/save.

I could come up with a hybrid solution that uses file_selector for desktop and file_picker for mobile, though the preference would be to get it to work without needing a mish-mash, if possible.

1 Like

I ended up using multiple libraries - one for desktop, one for mobile, and one for web. This is because file_picker wasn’t working for snap, but file_selector doesn’t work for mobile, and neither work for saving files when running on the web.

I’ve outlined it below for anyone else having this issue (the below is changed from my own code to make it simpler/clearer for the sake of the example).

pubspec.yaml

dependencies:
  file_picker: ^8.1.2
  file_selector: ^1.0.3

import_data.dart

import "package:file_picker/file_picker.dart";
import "package:file_selector/file_selector.dart";

Future<void> _openDesktop() async {
  XTypeGroup types = const XTypeGroup(
    label: "JSON",
    extensions: ["json"],
  );

  XFile? file = await openFile(
    acceptedTypeGroups: [types],
  );

  if (file != null) {
    String contents = await file.readAsString();
  }
}

Future<void> _openMobile() async {
  FilePickerResult? path = await FilePicker.platform.pickFiles(
    dialogTitle: "Open File",
    type: FileType.custom,
    allowedExtensions: ["json"],
    withReadStream: true,
    lockParentWindow: true,
  );

  if (result != null) {
    Stream<List<int>> stream = result.files.first.readStream!
    StringBuffer buffer = StringBuffer();

    stream.transform(utf8.decoder).listen((data) {
      buffer.write(data);
    },
    onError: (exception) {
      // Show an error message
    },
    onDone: () {
      String contents = buffer.toString();
    }
  }
}

Future<void> _openWeb() async {
  XTypeGroup types = const XTypeGroup(
    label: "JSON",
    extensions: ["json"],
  );

  FilePickerResult? result = openFile(
    acceptedTypeGroups: [types],
  );

  if (result != null) {
    String contents = await result.readAsString();
  }
}

export_data.dart (obviously the contents isn’t valid JSON, just providing an example)

import "package:file_picker/file_picker.dart";
import "package:file_selector/file_selector.dart";
import "package:ledger/web_empty.dart"
    if(dart.library.web) "package:web/web.dart";

Future<void> _saveDesktop() async {
  XTypeGroup types = const XTypeGroup(
    label: "JSON",
    extensions: ["json"],
  );

  FileSaveLocation? result = await getSaveLocation(
    acceptedTypeGroups: [types],
    suggestedName: "Data.json",
  );

  if (result != null) {
    await File(result.path).writeAsString("contents");
  }
}

Future<void> _saveMobile() async {
  await FilePicker.platform.saveFile(
    dialogTitle: "Save File",
    fileName: "Data.json",
    type: FileType.custom,
    allowedExtensions: ["json"],
    bytes: utf8.encode("contents"),
    lockParentWindow: true,
  );
}

Future<void> _saveWeb() async {
  String data = Uri.encodeComponent("contents");
  HTMLAnchorElement()
    ..href = "data:text/plain;charset=utf-8,$data"
    ..download = "Data.json"
    ..click();
}

web_empty.dart (I had to create this otherwise it wouldn’t compile for snap - see the conditional import in export_data.dart)

class HTMLAnchorElement {
  String download = "";
  String href = "";

  void click() {}
}

Hope this helps!

1 Like

Can you share the snap file with us? I believe this can be a portal issue and not a snap issue.

Hi @soumyaDghosh, if you mean the snapcraft.yaml file, it’s not changed since my first post. If you mean the actual compiled snap, the current version is available on an unlisted repo, while’s it’s still in beta (note that the current version, 0.7.0.0, uses the three libraries as described above, so it should hopefully work).

If you notice any issues in the app, please message me :slightly_smiling_face:

1 Like

Hi may be what you can do is, you can mail me, and we can talk about the code itself. Maybe I can work with you in that? I do have some experience on that thing.