How to Pick files and Images for upload with flutter web
Solution 1
Using dart:html
package directly in Flutter is not recommended.
Instead, use this package: https://pub.dev/packages/file_picker.
Example of how to use in Flutter Web:
class FileUploadButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text('UPLOAD FILE'),
onPressed: () async {
var picked = await FilePicker.platform.pickFiles();
if (picked != null) {
print(picked.files.first.name);
}
},
);
}
}
Note that FilePickerResult.path
is not supported in Flutter Web.
Solution 2
I tried the code below and it worked.
first import 'dart:html';
// variable to hold image to be displayed
Uint8List uploadedImage;
//method to load image and update `uploadedImage`
_startFilePicker() async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen((e) {
// read file content as dataURL
final files = uploadInput.files;
if (files.length == 1) {
final file = files[0];
FileReader reader = FileReader();
reader.onLoadEnd.listen((e) {
setState(() {
uploadedImage = reader.result;
});
});
reader.onError.listen((fileEvent) {
setState(() {
option1Text = "Some Error occured while reading the file";
});
});
reader.readAsArrayBuffer(file);
}
});
}
now just any Widget, like a button and call the method _startFilePicker()
Solution 3
import 'package:http/http.dart' as http;
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
class FileUploadWithHttp extends StatefulWidget {
@override
_FileUploadWithHttpState createState() => _FileUploadWithHttpState();
}
class _FileUploadWithHttpState extends State<FileUploadWithHttp> {
PlatformFile objFile = null;
void chooseFileUsingFilePicker() async {
//-----pick file by file picker,
var result = await FilePicker.platform.pickFiles(
withReadStream:
true, // this will return PlatformFile object with read stream
);
if (result != null) {
setState(() {
objFile = result.files.single;
});
}
}
void uploadSelectedFile() async {
//---Create http package multipart request object
final request = http.MultipartRequest(
"POST",
Uri.parse("Your API URL"),
);
//-----add other fields if needed
request.fields["id"] = "abc";
//-----add selected file with request
request.files.add(new http.MultipartFile(
"Your parameter name on server side", objFile.readStream, objFile.size,
filename: objFile.name));
//-------Send request
var resp = await request.send();
//------Read response
String result = await resp.stream.bytesToString();
//-------Your response
print(result);
}
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
//------Button to choose file using file picker plugin
RaisedButton(
child: Text("Choose File"),
onPressed: () => chooseFileUsingFilePicker()),
//------Show file name when file is selected
if (objFile != null) Text("File name : ${objFile.name}"),
//------Show file size when file is selected
if (objFile != null) Text("File size : ${objFile.size} bytes"),
//------Show upload utton when file is selected
RaisedButton(
child: Text("Upload"), onPressed: () => uploadSelectedFile()),
],
),
);
}
}
Solution 4
I've tested this package and was very happy with the result imagePickerWeb it returns 3 different types it can be in the form of Image(widget for preview), byte, File(upload)
then you can use this to get the values
html.File _cloudFile;
var _fileBytes;
Image _imageWidget;
Future<void> getMultipleImageInfos() async {
var mediaData = await ImagePickerWeb.getImageInfo;
String mimeType = mime(Path.basename(mediaData.fileName));
html.File mediaFile =
new html.File(mediaData.data, mediaData.fileName, {'type': mimeType});
if (mediaFile != null) {
setState(() {
_cloudFile = mediaFile;
_fileBytes = mediaData.data;
_imageWidget = Image.memory(mediaData.data);
});
}
Uploading to firebase
don't forget to add this to your index.html
<script src="https://www.gstatic.com/firebasejs/7.5.0/firebase-storage.js"></script>
Uploading to firebase
import 'package:firebase/firebase.dart' as fb;
uploadToFirebase(File file) async {
final filePath = 'temp/${DateTime.now()}.png';//path to save Storage
try {
fb
.storage()
.refFromURL('urlFromStorage')
.child(filePath)
.put(file);
} catch (e) {
print('error:$e');
}
}
See the documentation of the package if you still have problems
Solution 5
The accepted answer is indeed outdated. Like jnt suggested, https://pub.dev/packages/file_picker is a handy package, when it comes to implementing an image upload using Flutter Web.
The problem I was facing is to get a base64 representation of an image, since I was using it to store images in Firestore. As we know, dart:io
is not supported on Flutter Web and throws Unsupported operation: _Namespace
error. Hence, using File
and reading file's bytes was not an option. Luckily, the package provides API to convert the uploaded image to Uint8List
. Here is my implementation:
import 'package:file_picker/file_picker.dart';
...
FilePickerResult? pickedFile;
...
void chooseImage() async {
pickedFile = await FilePicker.platform.pickFiles();
if (pickedFile != null) {
try {
setState(() {
logoBase64 = pickedFile!.files.first.bytes;
});
} catch (err) {
print(err);
}
} else {
print('No Image Selected');
}
}
In case you need to display the local image right away, use Image.memory
.
Image.memory(logoBase64!);
Norbert
I am a passionate software developer who develops desktop,web and mobile(android&iOS with Flutter) software I am familiar with the following Dart Flutter Nodejs Reactjs Php mySQL Python html css
Updated on January 27, 2022Comments
-
Norbert about 2 years
I would like to know how to pick an Image from the users computer into my flutter web app for upload
-
grantespo over 3 yearsThis repo has been archived by the owner
-
Abdul Rafay over 3 yearsis there a way to detect if the file picker was canceled?
-
C. Skjerdal over 3 years@AbdulRafay my understanding for Web there isn't any cancelled callback.
-
Dean Villamia over 3 yearsyou could still fork the repo here github.com/Ahmadre/image_picker_web
-
sta over 3 yearsPlease add more details about your answer
-
Rahul Kushwaha about 3 yearsI am using this dependencies but not getting path .I have to upload it to firebase . THen what to use for flutter web to select file path for web
-
Rahul Kushwaha about 3 yearsCan we use it for flutter web
-
jnt about 3 yearsThis works in flutter web, but path is not needed, and is not implemented, as stated explicitly in the docs. Just use the
PlatformFile.bytes
property to access the bytes. -
Lad Khushbu about 3 years@RahulKushwaha Yes! It is working well in flutter web.
-
Rahul Kushwaha about 3 years@LadKhushbu It's giving me null aas path when choosing any .docs file .I am using pub.dev/packages/file_picker package.
-
Lad Khushbu about 3 years@RahulKushwaha Yes it will return null path in web, so use ReadStream to upload file.
-
Rahul Kushwaha about 3 years@LadKhushbu can you please share me details me how to use read stream and ?
-
Wesley Barnes about 3 yearsI'm finding it pretty hard to get an image uploaded with flutter web. This solution also gives error - <error>:<getObject: NoSuchMethodError: The getter 'uri' was called on null.> - Anyone know maybe why please?
-
Yogi Arif Widodo over 2 yearswhy i always get null on .bytes ?
-
Yogi Arif Widodo over 2 yearsthe request mimetype is
application/octet-stream
not image . -
AzureIP over 2 yearsMultipart request needs a Stream<List<int>>. How to get this from .bytes?
-
AzureIP over 2 yearsByteStream.fromBytes(bytes!.toList())
-
AzureIP over 2 yearsHow to deal with large files? This works only for around up to 537MB.
-
Santiago about 2 yearsThis is the easy part, you missed how to send it trough http and most importantly how to handle it on the server.
-
Benyamin about 2 years@LadKhushbu can you update this answer with null safety? in the readstream line it shows this error: Stream<List<int>>?' can't be assigned to the parameter type 'Stream<List<int>>
-
Benyamin about 2 yearsit shows this error for me: Unsupported operation: Platform._operatingSystem
-
Jeff Frazier about 2 yearsAgree with Santiago. This is easy, it's converting the bytes back to a File to upload to AWS that is hard to find an answer for.
-
Abdallah Ibrahim almost 2 years@Benyamin did you manage to convert this to null safety friendly? I am stuck on the same issue now..
-
Abdallah Ibrahim almost 2 yearsOK got it, it works for me now, need to put
objFile!.readStream!