mattreid1 / firebase_image

🔥 Cached Flutter ImageProvider for Firebase Cloud Storage
https://pub.dev/packages/firebase_image
ISC License
85 stars 69 forks source link

Gracefully handle File Not Exists #11

Open awhitford opened 4 years ago

awhitford commented 4 years ago

I have a scenario where a user may have uploaded a headshot image. There is no exists method for StorageReference, so the only way for one to really know if the user has an image is to try and download it. Alas, then I end up with messy stack traces, like:

flutter: ══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
flutter: The following PlatformException was thrown resolving an image codec:
flutter: PlatformException(Error -13010, FIRStorageErrorDomain, Object
flutter: headshots/QvCAc4WkJd8k0QthAUl1/headshot.jpg does not exist.)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
flutter: #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:156:18)
flutter: <asynchronous suspension>
flutter: #2      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
flutter: #3      MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:356:48)
flutter: #4      StorageReference.getMetadata (package:firebase_storage/src/storage_reference.dart:162:10)
flutter: #5      FirebaseImageCacheManager.upsertRemoteFileToCache (package:firebase_image/src/cache_manager.dart:145:48)
flutter: #6      FirebaseImage._fetchImage (package:firebase_image/src/firebase_image.dart:93:36)
flutter: <asynchronous suspension>
flutter: #7      FirebaseImage._fetchImageCodec (package:firebase_image/src/firebase_image.dart:106:38)
flutter: #8      FirebaseImage.load (package:firebase_image/src/firebase_image.dart:117:18)
flutter: #9      ImageProvider.resolveStreamForKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:501:13)
flutter: #10     ImageCache.putIfAbsent (package:flutter/src/painting/image_cache.dart:359:22)
flutter: #11     ImageProvider.resolveStreamForKey (package:flutter/src/painting/image_provider.dart:499:80)
flutter: #12     ScrollAwareImageProvider.resolveStreamForKey (package:flutter/src/widgets/scroll_aware_image_provider.dart:106:19)
flutter: #13     ImageProvider.resolve.<anonymous closure> (package:flutter/src/painting/image_provider.dart:330:9)
flutter: #14     ImageProvider._createErrorHandlerAndKey.<anonymous closure>.<anonymous closure> (package:flutter/src/painting/image_provider.dart:460:26)
flutter: #15     SynchronousFuture.then (package:flutter/src/foundation/synchronous_future.dart:41:29)
flutter: #16     ImageProvider._createErrorHandlerAndKey.<anonymous closure> (package:flutter/src/painting/image_provider.dart:457:11)
flutter: #20     ImageProvider._createErrorHandlerAndKey (package:flutter/src/painting/image_provider.dart:449:16)
flutter: #21     ImageProvider.resolve (package:flutter/src/painting/image_provider.dart:327:5)
flutter: #22     _ImageState._resolveImage (package:flutter/src/widgets/image.dart:1099:16)
flutter: #23     _ImageState.didChangeDependencies (package:flutter/src/widgets/image.dart:1052:5)

(and it keeps going)

It appears that the getMetadata call is causing the Not Found Exception. https://github.com/mattreid1/firebase_image/blob/d5cc7dff0bef8ac54fa62b27e05c5adf521893bd/lib/src/cache_manager.dart#L145

Can something be done to suppress this extensive stack trace output? I would be open to passing a flag that indicated that a File not found is OK; or perhaps an onFileNotFound handler?

My code can really ignore it. The image, since it does not exist, is never provided, so my image place holder is simply never replaced. But the excessive stack traces are a huge distraction and it cries wolf.

awhitford commented 4 years ago

My workaround is that my code first calls getMetadata and then it will only continue to call FirebaseImage when the metadata call succeeds. One redundant metadata call is a small price to pay.