How to handle Firebase Storage StorageException

Viewed 1837

My app gets images from Firebase storage. In the event that there exist no image I want to be able to handle the error. But I can't seem to get it working.

I have tried surrounding with try catch.

I have tried this

Future<dynamic> getImage(int index){
      return FirebaseStorage.instance.ref().child(widget.snap[index].data['英文品名']+".jpg").getDownloadURL().catchError((onError){
        print(onError);
      }); 
 }

and this

 Future<dynamic> getImage(int index){
   var imageStream;
   try {
       imageStream = FirebaseStorage.instance.ref().child(widget.snap[index].data['英文品名']+".jpg").getDownloadURL();    
   } catch (e) {
     print(e);
   }
   return imageStream;
 }

but I always get unhandled exception error and my app crashes.

E/StorageException(11819): StorageException has occurred.
E/StorageException(11819): Object does not exist at location.
E/StorageException(11819):  Code: -13010 HttpResult: 404
E/StorageException(11819): StorageException has occurred.
E/StorageException(11819): Object does not exist at location.
E/StorageException(11819):  Code: -13010 HttpResult: 404
E/StorageException(11819): {  "error": {    "code": 404,    "message": "Not Found.  Could not get object",    "status": "GET_OBJECT"  }}
E/StorageException(11819): java.io.IOException: {  "error": {    "code": 404,    "message": "Not Found.  Could not get object",    "status": "GET_OBJECT"  }}

How to handle this exception? Image of exception in VS Code

3 Answers

Uploading the File will take different time based on the size of the Image. So most probably your error is because of the wrong combination of async and await. This code works for me.

Future<String> uploadSingleImage(File file) async {
    //Set File Name
    String fileName = DateTime.now().millisecondsSinceEpoch.toString() +
        AuthRepository.getUser().uid +
        '.jpg';
    
    //Create Reference
    Reference reference = FirebaseStorage.instance
        .ref()
        .child('Single Post Images')
        .child(fileName);

    //Now We have to check status of UploadTask
    UploadTask uploadTask = reference.putFile(file);
    
    String url;
    await uploadTask.whenComplete(() async {
      url = await uploadTask.snapshot.ref.getDownloadURL();
    });
    print('before return');
    return url;
  }

The error is thrown because you are trying to access the download url at a time where it hasn't been created yet.

You can wrap your upload code in an if statement like the example below. This way you guarantee that the upload task has completed successfully.

 if(storageRef
        .child(folderName)
        .putFile(fileName).isSuccessful)
      {
        url = await storage.child("folderName").child(fileName).getDownloadURL();
      }

You can check if an Object exists or not like this:

     import 'package:firebase_core/firebase_core.dart' as firebase_core;
        try {
          FirebaseStorage.instance
          .ref()
          .child(widget.snap[index].data['英文品名']+".jpg")
          .getDownloadURL()
        } on firebase_core.FirebaseException catch(error) {
          // if the Object does not exists
          if (error.code == 'object-not-found')) {
              //DO something
          }
        
        }
Related