5

I am trying to achieve a simple file upload feature in my flutter app. I need to have it for both web and mobile.

            ///
        class FileUploadController extends GetxController {
          Rx<File?> file = Rx<File?>(null);
          String fileName = '';
          var token =
              'something';

          void pickFile() async {
            try {
              FilePickerResult? result = await FilePicker.platform.pickFiles(
                //type: FileType.image,
                allowMultiple: false,
              );

              if (result != null) {
                if (kIsWeb) {
                  Uint8List? fileBytes = result.files.first.bytes;
                  fileName = result.files.first.name;
                  var objFile = await createFileFromBytes(fileBytes);
                  file.value = objFile;
                } //
                else {
                  file.value = File(result.files.single.path!);
                }
              }
            } //
            catch (e) {
              print(e);
            }
          }

          Future<File> createFileFromBytes(Uint8List? bytes) async {
            var cleanString = '';
            var lstBytes = bytes!.toList();
            // Decode the bytes as a UTF-8 string
            String decodedCode = utf8.decode(lstBytes, allowMalformed: true);
            if (decodedCode.contains('�')) {
              cleanString = decodedCode.replaceAll('�', '');
            }

            // Create a File object from the decoded string
            var file = File.fromRawPath(Uint8List.fromList(cleanString.codeUnits));
            return file;
          }

          void uploadFile() async {
            try {
              if (file.value == null) {
                return;
              }

              // Set API endpoint URL
              Uri uri =
                  Uri.parse('xxxx');

              // Create multipart request
              var request = http.MultipartRequest('POST', uri);

              request.fields.addAll({
                "facility_id": "380",
                "module_id": "1",
                "id": "3263",
              });

              // Add file to request
              String fieldName = 'files';
              fileName = kIsWeb ? fileName : file.value!.path.split('/').last;
              var checkFile = file.value;
    //// getting error here: Un
              var bytesData = await file.value!.readAsBytes();
              request.files.add(http.MultipartFile.fromBytes(
                fieldName,
                bytesData,
                filename: fileName,
              ));

              // Set headers
              request.headers.addAll({
                "Authorization": "Bearer $token",
                "Content-Type": "multipart/form-data",
                "Content-Length": file.value!.lengthSync().toString(),
                "Accept": "*/*",
              });

              // Send request
              var response = await request.send();

              // Check response status code
              if (response.statusCode == 200) {
                print('File uploaded successfully!');
              } else {
                print('Error uploading file.');
              }
            } //
            catch (e) {
              print(e);
            }
          }

          ///
        }

Error: Unsupported Operation _Namespace

who-aditya-nawandar
  • 1,334
  • 9
  • 39
  • 89

3 Answers3

1
 Future<Map<dynamic, dynamic>?> getImage(String url) async {
  try {
    PlatformFile  _paths = (await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowMultiple: false,
      onFileLoading: (FilePickerStatus status) =>
      allowedExtensions: ['png', 'jpg', 'jpeg', 'heic'],
    ))
        ?.files;
  } on PlatformException catch (e) {
    log('Unsupported operation' + e.toString());
  } catch (e) {
    log(e.toString());
  }
  if (_paths != null) {
    var res = await ApiClient.uploadImage( _paths!.first.bytes!, _paths!.first.name);
    return {'fileId': res, 'data': _paths};
  } else {
    return null;
  }
}

upload image 
var dio = Dio();
dio.options.headers['content-Type'] = 'application/json';
dio.options.headers["Authorization"] = "Bearer $token";
FormData formData = FormData.fromMap({
  "file": MultipartFile.fromBytes(
    file,
    filename: fileName,
  ),
  // 'companyId':data['companyId'],
});

var response = await dio.post(url, data: formData);
var responseBody = response.data;

In above code after picking file from device (mobile or web) _path variable contain the all the information(bytes, path, name and other information about the image) here in my code ApiClient.uploadImage is an API call which takes image bytes and image name , upload it to the AWS server and return the fileId.

0

Probably not the answer you are looking for, but I am able to upload files from my flutter app (web & mobile) using the share_plus package.

void uploadFile() async {
  try {
    if (file.value == null) {
      return;
    }
    final box = ctx.findRenderObject() as RenderBox?;
    final appDir = await getApplicationDocumentsDirectory();
    final file = File(appDir.path + "/user_data");
    Share.shareXFiles(
      [XFile(file.path)],
      subject: "user_data",
      sharePositionOrigin: rect ?? box!.localToGlobal(Offset.zero) & box.size,
    );
  } catch (e) {
    print(e);
  }
}
Firas AT
  • 428
  • 3
  • 4
0

Just use the dart:html library when running on the web. E.g.:

import 'dart:html' as html;

Future<File> createFileFromBytes(Uint8List? bytes) async {
  if (kIsWeb) {
    // Save the file in browser's temp storage
    final blob = html.Blob([bytes]);
    final url = html.Url.createObjectUrlFromBlob(blob);

    // Create a File object from the URL
    final file = File(url);
    return file;
  } else {
    // Your previous code here
  }
}

Now the code uses html.Blob for web environments, and it should work for both mobile and web. Just add the import dart:html as html; line at the beginning of your file. That's it!

SolessChong
  • 3,370
  • 8
  • 40
  • 67