Flutterfire: [firebase_storage] to handle errors like a security error

Created on 13 Oct 2019  路  11Comments  路  Source: FirebaseExtended/flutterfire

I want to handle errors like security error
PlatformException(sign_in_failed, FIRStorageErrorDomain, User does not have permission to access

I tried try catch block but no luck.

try {
      final StorageUploadTask uploadTask = ref.putFile(_image,StorageMetadata(contentType:'image/jpeg'));
      final Uri downloadUrl = (await uploadTask.future).downloadUrl;
      print(downloadUrl.toString());
    } on PlatformException catch (e) {
      throw  e.code;
    } catch (e) {
      print(e);
    }
android storage wontfix bug

Most helpful comment

This works for me.

try {    
    String url = await storageReference.getDownloadURL();
} on Exception catch(e) {
    print("Oops! The file was not found");
}

All 11 comments

@volkangurol

The issue at https://github.com/flutter/flutter/issues/18547 has been closed and moved here. Future collaboration on this issue will be done here.

Maybe that wasn't the same issue as I thought. I wasn't able to catch errors when using

storageReference.getDownloadURL().then((_) async { ..... }, onError: (e) {

Thanks to architecture changes I was able to use async/await properly and I'm now catching issue

   try {    
await storageReference.getDownloadURL();
    StorageFileDownloadTask storageFileDownloadTask;
    storageFileDownloadTask = storageReference.writeToFile(image);
    final int byteNumber =
        (await storageFileDownloadTask.future).totalByteCount;
    debugPrint('downloaded image size ${byteNumber.toString()}');
    } on Exception catch(e) {
      return Left(e);
    }

In my case I'd like to display an error message if the file doesn't upload due to security rules restrictions. The debug console outputs the below but I can't catch anything.

E/StorageException( 5833): StorageException has occurred.
E/StorageException( 5833): User does not have permission to access this object.
E/StorageException( 5833):  Code: -13021 HttpResult: 403
E/StorageException( 5833): The server has terminated the upload session
E/StorageException( 5833): java.io.IOException: The server has terminated the upload session
E/StorageException( 5833):  at com.google.firebase.storage.UploadTask.serverStateValid(com.google.firebase:firebase-storage@@17.0.0:340)
E/StorageException( 5833):  at com.google.firebase.storage.UploadTask.shouldContinue(com.google.firebase:firebase-storage@@17.0.0:309)
E/StorageException( 5833):  at com.google.firebase.storage.UploadTask.run(com.google.firebase:firebase-storage@@17.0.0:226)
E/StorageException( 5833):  at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage@@17.0.0:1106)
E/StorageException( 5833):  at com.google.firebase.storage.StorageTask$$Lambda$10.run(Unknown Source:2)
E/StorageException( 5833):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/StorageException( 5833):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/StorageException( 5833):  at java.lang.Thread.run(Thread.java:919)
E/StorageException( 5833): Caused by: java.io.IOException: {  "error": {    "code": 403,    "message": "Permission denied. Could not perform this operation"  }}
E/StorageException( 5833):  at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@17.0.0:455)
E/StorageException( 5833):  at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@17.0.0:435)
E/StorageException( 5833):  at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage@@17.0.0:426)

The exception is being recognized in the subscription but I'm not sure what to do with that:

try {
  FirebaseStorage _storage =
      await RootProject.getStorage(StorageBucket.users);
  StorageUploadTask _uploadTask = _storage.ref().child('path').putFile(
        file,
      );

  final StreamSubscription<StorageTaskEvent> streamSubscription =
      _uploadTask.events.listen((event) {
    if (event.type == StorageTaskEventType.failure) {
      // works but ...
    }
  });

  await _uploadTask.onComplete;
  streamSubscription.cancel();
} catch (e) {
  // nothing ...
}

Maybe that wasn't the same issue as I thought. I wasn't able to catch errors when using

storageReference.getDownloadURL().then((_) async { ..... }, onError: (e) {

Thanks to architecture changes I was able to use async/await properly and I'm now catching issue

   try {    
await storageReference.getDownloadURL();
    StorageFileDownloadTask storageFileDownloadTask;
    storageFileDownloadTask = storageReference.writeToFile(image);
    final int byteNumber =
        (await storageFileDownloadTask.future).totalByteCount;
    debugPrint('downloaded image size ${byteNumber.toString()}');
    } on Exception catch(e) {
      return Left(e);
    }

it doesn't catch anything, and it's better to add await before storageReference.getDownloadURL()

This works for me.

try {    
    String url = await storageReference.getDownloadURL();
} on Exception catch(e) {
    print("Oops! The file was not found");
}

I have this issue as well - however much I await and try / catch the executions are still filling up my debug console and it drives me nuts. Any updates on this at all would be very much appreciated !

@samarthagarwal doesn't seem to work for me... Environment and package versions all up to date, any further help gratefully received ;-)

try {
        final StorageReference ref =
            FirebaseStorage.instance.ref().child(_remote.path);
        final dynamic url = await ref.getDownloadURL();        
      } on Exception  catch (error) {
        print('error');
      }
[鈭歖 Flutter (Channel dev, v1.15.3, on Microsoft Windows [Version 10.0.18363.657], locale en-GB)
[鈭歖 Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[鈭歖 Android Studio (version 3.5)
[鈭歖 VS Code (version 1.42.1)
[鈭歖 Connected device (1 available)
  cupertino_icons: ^0.1.2
  firebase_auth: ^0.15.4
  cloud_firestore: ^0.13.4
  firebase_storage: ^3.1.3
  provider: ^4.0.2
  flutter_spinkit: ^4.1.1+1
  intro_slider: ^2.2.9
  cached_network_image: ^2.0.0
  google_maps_flutter: ^0.5.24+1
  flutter_cache_manager: ^1.1.3



md5-1f0416413757c4a5bc18f261f305a78c



E/StorageException(21824): StorageException has occurred.
E/StorageException(21824): Object does not exist at location.
E/StorageException(21824):  Code: -13010 HttpResult: 404
E/StorageException(21824): {  "error": {    "code": 404,    "message": "Not Found.  Could not get object",    "status": "GET_OBJECT"  }}
E/StorageException(21824): java.io.IOException: {  "error": {    "code": 404,    "message": "Not Found.  Could not get object",    "status": "GET_OBJECT"  }}
E/StorageException(21824):  at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@17.0.0:455)
E/StorageException(21824):  at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@17.0.0:435)
E/StorageException(21824):  at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage@@17.0.0:426)
E/StorageException(21824):  at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@17.0.0:280)
E/StorageException(21824):  at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@17.0.0:294)
E/StorageException(21824):  at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@17.0.0:70)
E/StorageException(21824):  at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@17.0.0:62)
E/StorageException(21824):  at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage@@17.0.0:74)
E/StorageException(21824):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/StorageException(21824):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/StorageException(21824):  at java.lang.Thread.run(Thread.java:919)

@mistyn8 You are right. It worked for me but now it does not. I don't remember the version I was using.

@samarthagarwal cheers for the reply.. so regression issue?

The issue I am facing is probably related to this.
The code:

await FirebaseStorage.instance
    .ref()
    .child("users_profilepics/" + _userUid)
    .getDownloadURL()
    .then((val) => _profileImageUrl = val)
    .catchError((err) {
           _profileImageUrl = "none";
           print("Profile pic not found.");
     });

Produces the aforementioned debug message in the console:
```Object does not exist at location.
E/StorageException(20215): Code: -13010 HttpResult: 404
E/StorageException(20215): { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
E/StorageException(20215): java.io.IOException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
E/StorageException(20215): at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@17.0.0:455)
E/StorageException(20215): at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@17.0.0:435)
......................


However, the **catchErr works well**, because the message "Profile pic not found" is written in the console, and the _profileImageUrl variable is set to none.

The result is exactly the same with the similar (maybe more correct?) code:

var profilePicLocation = FirebaseStorage.instance
.ref()
.child("users_profilepics/" + _userUid);

try {
_profileImageUrl = await profilePicLocation.getDownloadURL();
}
on Exception catch(e) {
_profileImageUrl = "none";
print("Profile pic not found.");
}
```
Also here the exception is caught ("Profile pic not found" is printed), but the error in the console is still written.

I think this is working as intended; you can catch the error but it still logs, these error logs you are seeing are Java stack traces coming from the native Firebase Android SDK - it logs errors by default, the plugin code itself for FlutterFire isn't logging/printing these as far as I can see.

Having said that we will be working on improved error handling across the board, e.g. #1456 #1223

Was this page helpful?
0 / 5 - 0 ratings