Flutter web - Upload Image File to Firebase Storage

14,128

Solution 1

Finally I managed to find a solution to this issue. To achieve this I needed to install two dependencies, firebase and universal_html. Yet difficult to find out the solution, its implementation was actually simple. Here is the code of the function I used to upload the html image file to Firebase Storage, into the "images" folder:

import 'dart:async';
import 'package:universal_html/prefer_universal/html.dart' as html;
import 'package:firebase/firebase.dart' as fb;

Future<Uri> uploadImageFile(html.File image,
      {String imageName}) async {
    fb.StorageReference storageRef = fb.storage().ref('images/$imageName');
    fb.UploadTaskSnapshot uploadTaskSnapshot = await storageRef.put(image).future;
    
    Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
    return imageUri;
}

I hope it helps someone with the same need as me.

Solution 2

After Combining so many posts I did it, and it works!

No, you just don't need any Kind of Universal_HTML or another image_picker_web. Just stick with Image Picker(https://pub.dev/packages/image_picker). And use the below code as I have used to upload the Image to Firebase Storage, and it works in all the way IOS, Android, Web, I hope you've already added the permission for ios and android. Let's Begin!

Import

import 'package:firebase_storage/firebase_storage.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as Path;

Call this method when you want to open a file picker in any of the above platforms!

chooseImage() async {
PickedFile? pickedFile = await ImagePicker().getImage(
      source: ImageSource.gallery,
    );
}

now you've file in pickedFile use kIsWeb to find out if it's web or not!

uploadImageToStorage(PickedFile? pickedFile) async {
if(kIsWeb){
Reference _reference = _firebaseStorage
        .ref()
        .child('images/${Path.basename(pickedFile!.path)}');
    await _reference
        .putData(
      await pickedFile!.readAsBytes(),
      SettableMetadata(contentType: 'image/jpeg'),
    )
        .whenComplete(() async {
      await _reference.getDownloadURL().then((value) {
        uploadedPhotoUrl = value;
      });
    });
 }else{
//write a code for android or ios
}

}

Solution 3

Here is the complete snip that work for me for uploading image: html.File doesn't work for me, the file is uploaded but you will see Error loading preview in firebase storage, so just passing the bytes directly work for me.

To show an image you can use mediaInfo.bytes with widget that support bytes e.g FadeInImage you can use MemoryImage(mediaInfo.bytes) and Image.memory(mediaInfo.bytes)

packages used:

  1. firebase
  2. image_picker_web
  3. path
  4. mime_type
    Future<MediaInfo> imagePicker() async {    
        MediaInfo mediaInfo = await ImagePickerWeb.getImageInfo;
        return mediaInfo;
     }
     
     Future<Uri> uploadFile(
          MediaInfo mediaInfo, String ref, String fileName) async {
        try {
          String mimeType = mime(Path.basename(mediaInfo.fileName));

          // html.File mediaFile =
          //     new html.File(mediaInfo.data, mediaInfo.fileName, {'type': mimeType}); 
          final String extension = extensionFromMime(mimeType);

          var metadata = fb.UploadMetadata(
            contentType: mimeType,
          );

          fb.StorageReference storageReference =
              fb.storage().ref(ref).child(fileName + ".$extension");

          fb.UploadTaskSnapshot uploadTaskSnapshot =
              await storageReference.put(mediaInfo.data, metadata).future;

          Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
          print("download url $imageUri");
          return imageUri;
        } catch (e) {
          print("File Upload Error $e");
          return null;
        }
      }

Solution 4

To access Cloud Storage in your Flutter for Web application, you can use the firebase-dart plugin. You can find an example of accessing storage through firebase-dart in the repo.

Share:
14,128
JDE10
Author by

JDE10

Updated on June 08, 2022

Comments

  • JDE10
    JDE10 almost 2 years

    On flutter web, I pick an image file from the computer and get a File image object. Then I want to upload it to Firebase Storage. For Android and iOS versions of the app I was using a Firebase Cloud Function and an http multipart request. It worked, but for the web version of the app it doesn't. So,

    How can I upload an html image file to Firebase Storage, either directly or through a Cloud Function?

  • shinriyo
    shinriyo almost 4 years
    upload was success but not open. header?
  • Rony Tesler
    Rony Tesler over 3 years
    How do you get the html.File?
  • Darari Nur Amali
    Darari Nur Amali over 3 years
    @shinriyo I got the same problem, file corrupted. What should I do?
  • Clement Osei Tano
    Clement Osei Tano over 3 years
    You made my day! Thanks for the answer
  • grantespo
    grantespo over 3 years
    Why import that universal_html library, when you can just use import 'dart:html' as html;?
  • Prince Hodonou
    Prince Hodonou over 3 years
    Going of this answer, what worked for me is using image_picker_for_web to get the image. Then turning that image into base64 encoding and using putString instead of put like the above. More documentation on putString can be found here
  • Asbah Riyas
    Asbah Riyas over 3 years
  • Frank van Puffelen
    Frank van Puffelen over 3 years
  • RoyalCoder
    RoyalCoder almost 3 years
    Hi Prince Hodonou, can you please post an example thanks in advance!
  • greybeard
    greybeard almost 3 years
    (quoting and decoration are not properly nested)