Home > Software design >  Best way to handle uploading and displaying Uint8List to FirebaseStorage
Best way to handle uploading and displaying Uint8List to FirebaseStorage

Time:12-29

Here is one of the children Widget that handles picking the image from a browser. ProfileImage is a custom widget that basically displays the images and has the ability to customize what happens when the image is clicked. Nothing too special or out of the oridinary.

ProfileImage(
    image: imageAvailable ? Image.memory(imageFile) : Image.network(fakeUser.imagePath),
    isEdit: true,
    onClicked: () async {
      setState(() {
        imageFile = Uint8List(0);
        imageAvailable = false;
      });
      final image = await ImagePickerWeb.getImageAsBytes();
      if (image!.isNotEmpty) {
        setState(() {
          imageFile = image;
          imageAvailable = true;
       });
     }
   })

I have this async method that handles the uploading process of the image picked once the user is finished. This is the last step in the process before the page pops out of context.

Future<void> uploadProfileImage() async {
  FirebaseStorage uploadRef = FirebaseStorage.instance;
  final UploadTask uploadTask = uploadRef
    .ref()
    .child(fakeUser.uuid)
    .child('profile-image')
    .putData(imageFile, SettableMetadata(contentType: "image/jpeg"));
  var downloadUrl = await (await uploadTask).ref.getDownloadURL();
  var url = downloadUrl.toString();
  fakeUser = fakeUser.copy(imagePath: url); // SharedPreferences to save userData locally
}

When I upload to FirebaseStorage, the data is shown in the web interface, but the file seems to be just bytes. Using Image.network(url) does not work and gives me the network image is not loading error or just a white image. I noticed the url does not have an extension or anything and when I put the url in the address bar it instantly starts downloading the file that I can't open. I would expect that the url would lead me to an actual image instead of downloading it.

Is there a better way to upload an image to FirebaseStorage for web users or should I be displaying the image a different way?

One idea I saw was to download the file using http GET and use that the response data for Image.network(), but I would like to refrain from downloading each time. Just using imageUrls would be better for my application.

CodePudding user response:

instead of using Uint8List use the method putFile provided by FirebaseStorage to upload the file & you'll direct be able to fetch the URL of image or any type of file .

Example :

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("images/${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();

CodePudding user response:

I used this repo as a reference. Using a PickedFile to upload to FirebaseStorage with putData worked as expected.

Then needed to configure CORS for my Firebase Project to get the image to display properly.

  • Related