27

I get an image from Firebase Storage, take a photo with the camera, or pick one from the Library. When one of these is complete, I have a class which stores an Image so that I can use it when required.

Now I need to upload this image to Firebase Storage (modified or new, doesn't matter). Firebase allows me to use one of the following: putData or putFile, each needing either an Uint8List or File respectively.

How can I take my Image and either get a File or Uint8List from it for uploading?

--

Alternatively to remedy this, how can I get a File of my image when I retrieve it from Firebase Storage?

Either way results in providing the correct data type to upload the image, be it get a File at the start or end.

11 Answers 11

25

When you select an image with the image picker, it returns a File, you can use await to wait until the user selects a file then store it as a File. Here is some sample code of how you can get the file from the image picker and upload it to Firebase.

    FirebaseStorage _storage = FirebaseStorage.instance;

    Future<Uri> uploadPic() async {

    //Get the file from the image picker and store it 
    File image = await ImagePicker.pickImage(source: ImageSource.gallery);  

    //Create a reference to the location you want to upload to in firebase  
    StorageReference reference = _storage.ref().child("images/");

    //Upload the file to firebase 
    StorageUploadTask uploadTask = reference.putFile(file);

    // Waits till the file is uploaded then stores the download url 
    Uri location = (await uploadTask.future).downloadUrl;

    //returns the download url 
    return location;
   }
Sign up to request clarification or add additional context in comments.

5 Comments

I think that this answer is not good because it does not specifically explain the concept of uploading an Image to Firebase Storage. It looks more like a code snippet from an actual application.
An Image is a file and the example demonstrates how to upload a file to Firebase Storage, if you would like to know the inner working of Firebase, I suggest you read the documentation.
The answer supplies comments that make it easy enough to file. I believe this answer is sufficient.
I know this is an old answer, but just wanted to check if this is still valid. future doesn't exist on uploadTask.
The above way has been deprecated, now you have to do the following: stackoverflow.com/a/64764390/7015400
7

Sorry for my late answer but the above answers are a bit old, Hope my answer will help you. The below example of code will work on the following dependencies.

On the question, it says how can I retrieve it after uploading. You can use the download URL to get the file or the image, you can download it or you can show it on the NetworkImage widget to display it to your user. I have shown below how to get the download URL.

pubspec.yaml

dependencies
    image_picker: ^0.6.5
    firebase_storage: ^3.1.5

Dart Code

//Creating a global Variable    
StorageReference storageReference = FirebaseStorage.instance.ref();
File _image;

void getImage(){
    _image = await ImagePicker.pickImage(source: ImageSource.gallery); 
}

void addImageToFirebase(){


    //CreateRefernce to path.
    StorageReference ref = storageReference.child("yourstorageLocation/");

    //StorageUpload task is used to put the data you want in storage
    //Make sure to get the image first before calling this method otherwise _image will be null.

    StorageUploadTask storageUploadTask = ref.child("image1.jpg").putFile(_image);

     if (storageUploadTask.isSuccessful || storageUploadTask.isComplete) {
          final String url = await ref.getDownloadURL();
          print("The download URL is " + url);
     } else if (storageUploadTask.isInProgress) {

          storageUploadTask.events.listen((event) {
          double percentage = 100 *(event.snapshot.bytesTransferred.toDouble() 
                               / event.snapshot.totalByteCount.toDouble());  
          print("THe percentage " + percentage.toString());
          });

          StorageTaskSnapshot storageTaskSnapshot =await storageUploadTask.onComplete;
          downloadUrl1 = await storageTaskSnapshot.ref.getDownloadURL();

          //Here you can get the download URL when the task has been completed.
          print("Download URL " + downloadUrl1.toString());

     } else{
          //Catch any cases here that might come up like canceled, interrupted 
     }

}

Comments

6

To pick image(gallery,camera.. etc) first you can use image Picker package

then get image as file like this

//Get the file from the image picker and store it
final pickedFile = await picker.getImage(source: ImageSource.camera);

  File image;
  if (pickedFile != null) {
    image = File(pickedFile.path);
  } else {
    print('No image selected.');
    return;
  }

then detect what reference you want to save this file image

FirebaseStorage storage = FirebaseStorage.instance;
//Create a reference to the location you want to upload to in firebase
StorageReference reference = storage.ref().child("profileImages/myImageUid");

finally start upload and wait until complete then get URL image

//Upload the file to firebase
        StorageUploadTask uploadTask = reference.putFile(image);
    
        StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
    
        // Waits till the file is uploaded then stores the download url
        String url = await taskSnapshot.ref.getDownloadURL();
    

Full Code

FirebaseStorage storage = FirebaseStorage.instance;

    File image;
    try {
      //Get the file from the image picker and store it
      image = await ImagePicker.pickImage(source: ImageSource.gallery);

    } on PlatformException catch (e) {
      //PlatformException is thrown with code : this happen when user back with don't
      //selected image or not approve permission so stop method here 
      // check e.code to know what type is happen
      return;
    }

    //Create a reference to the location you want to upload to in firebase
    StorageReference reference =
        storage.ref().child("profileImages/${user.id}");

    //Upload the file to firebase
    StorageUploadTask uploadTask = reference.putFile(image);

    StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;

    // Waits till the file is uploaded then stores the download url
    String url = await taskSnapshot.ref.getDownloadURL();

Comments

5

Meanwhile, there is a library which helps you...

  1. selecting
  2. cropping, compressing
  3. uploading an image to firebase storage.

The library is called firebase_picture_uploader and can be used like that (Excerpt from Source):

new PictureUploadWidget(
  onPicturesChange: profilePictureCallback,
  initialImages: _profilePictures,
  settings: PictureUploadSettings(onErrorFunction: onErrorCallback),
  buttonStyle: const PictureUploadButtonStyle(),
  buttonText: 'Upload Picture',
  enabled: true,
)

Firebase Picture Uploader Example:

Firebase Picture Uploader Example

Comments

2

When you pick your image from gallery or camera

just use below mentioned function to get the file name with extension

basename(image.path)

and then pass the file to firebase Storage Reference with the path you want to upload to with the file name, you don't have to think about the extension of the file then.

Libraries used

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

Code:

upload() async {
   //pick image   use ImageSource.camera for accessing camera. 
   File image = await ImagePicker.pickImage(source: ImageSource.gallery);

   //basename() function will give you the filename
   String fileName = basename(image.path);

   //passing your path with the filename to Firebase Storage Reference
   StorageReference reference =
        FirebaseHelper.firebaseStorage().child("your_path/$fileName");

   //upload the file to Firebase Storage
   StorageUploadTask uploadTask = reference.putFile(image);

   //Snapshot of the uploading task
   StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
}

1 Comment

i think this is best approach
2
  ImagePicker imagePicker = ImagePicker();
      File file;
      String imageUrl;

// Image Picker

  Future pickImageCamera() async {
    var image = await imagePicker.pickImage(source: ImageSource.camera);
    if (image != null) {
      setState(() {
        file = File(image.path);
      });
    }
  }

// Upload Picked Image to FireStore

  uploadProfileImage() async {
    Reference reference = FirebaseStorage.instance
        .ref()
        .child('profileImage/${Path.basename(file.path)}');
    UploadTask uploadTask = reference.putFile(file);
    TaskSnapshot snapshot = await uploadTask;
    imageUrl = await snapshot.ref.getDownloadURL();
    print(imageUrl);
  }

Comments

1

If you're using firebase_storage >= 5.0.0-dev.1 the class StorageReference has been renamed to Reference.

I meant that the newer versions of Firebase do not use the format:

// passing your path with the filename to Firebase Storage Reference StorageReference reference = FirebaseHelper.firebaseStorage (). Child ("your_path/ $ fileName");

the correct one would be: Reference reference = FirebaseHelper.firebaseStorage (). Child ("your_path / $ fileName");

3 Comments

Answer unclear, would be better to provide some code or more information
I meant that the newer versions of Firebase do not use the format: // passing your path with the filename to Firebase Storage Reference StorageReference reference = FirebaseHelper.firebaseStorage (). Child ("your_path / $ fileName"); the correct one would be: Reference reference = FirebaseHelper.firebaseStorage (). Child ("your_path / $ fileName");
Looks good, why don't you put that into your answer?
1

Very late to answer. But this might help someone. Here is the my approach to get Image from gallery first and then upload Image to Firebase. I hope you would like this approach

XFile? image;
ImagePicker().pickImage(source: ImageSource.gallery,).then((value) {
        setState(() {
        image = value;
              });
  });
FirebaseStorage.instance.ref("desiredPathForImage/").putFile(File(image!.path))
 .then((TaskSnapshot taskSnapshot) {
  if (taskSnapshot.state == TaskState.success) {
      print("Image uploaded Successful");
      // Get Image URL Now
      taskSnapshot.ref.getDownloadURL().then(
      (imageURL) {
      print("Image Download URL is $imageURL");
      });
     } 
  else if (taskSnapshot.state == TaskState.running) {
      // Show Prgress indicator
      }
  else if (taskSnapshot.state == TaskState.error) {
      // Handle Error Here
      }
   });

Comments

1
  firebase_core: ^1.10.3
  firebase_analytics: ^9.0.0
  firebase_messaging: ^11.2.1
  firebase_storage: ^10.2.4
  image_picker: ^0.8.4+4

import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;


Future<void> uploadImageToFirebase(XFile? image) async {
Directory appDocDir = await getApplicationDocumentsDirectory();
String filePath = 'directoryName/${image?.path.split("/").last}';
File file = File(image?.path ?? "");
try {
  TaskSnapshot uploadTask = await firebase_storage.FirebaseStorage.instance
      .ref(filePath)
      .putFile(file);
  String? url = await uploadTask.ref.getDownloadURL();
  print("download url : $url");
  vm.pickedImages[index] = url;
} on FirebaseException catch (e) {
  // e.g, e.code == 'canceled'
}

}

Comments

0

firebase_storage: ^3.0.6, image_picker: ^0.6.1 this two libraries you must be used

after that for getting the image

  Future getImage() async {
    var tempImage = await ImagePicker.pickImage(source: ImageSource.gallery);

    setState(() {
      sampleImage = tempImage;
     });
  }

and now upload the image

Widget enableUpload() {
return Container(
  child: Column(
    children: <Widget>[
      Image.file(sampleImage, height: 300.0, width: 300.0),
      RaisedButton(
        elevation: 7.0,
        child: Text('Upload'),
        textColor: Colors.white,
        color: Colors.blue,
        onPressed: () {
          final StorageReference firebaseStorageRef =
              FirebaseStorage.instance.ref().child('myimage.jpg');
          final StorageUploadTask task =
              firebaseStorageRef.putFile(sampleImage);

        },
      )
    ],
  ),
);
}

you can use this enableUpload() widget where you want.

Comments

0

ImagePicker helps to get the file from the gallery/camera and uploading it using FirebaseStorage. getDownloadURL() method gives us the download URL which uploaded to firebase.

Future uploadImageToFirebase(BuildContext context) async {
        final picker = ImagePicker();
        final pickedFile = await picker.getImage(source: ImageSource. gallery);
        File image = new File(pickedFile.path);

        var reference = FirebaseStorage.instance.ref().child('last_image/car5'); // Modify this path/string as your need
        StorageUploadTask uploadTask = reference.putFile(file);
        StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
        taskSnapshot.ref.getDownloadURL().then(
              (value) => print("Download URL: $value"),
            );
      }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.