I spent my day refactoring my entire project, shifting from saving the download URL to storing the reference path. Wondering why? Initially, I considered:
- Avoiding saving both because it felt redundant and costly.
- Thinking to save only the download URL is smart, beacause i need just this value in my application and if I ever needed the reference, I could just invoke the refFromUrl method.
However, this approach posed some issues:
- Currently (firebase_storage version 11.6.0), there's an issue with the refFromUrl method when using the emulator. Consequently, it is not possible to get the Image Reference during the testing phase, which is a significant problem.
- The Download Link is a public link, raising security concerns. Anyone can access the link and potentially request your image. Firestore lacks the ability to set a scaling/download limit, meaning if someone decides to request your image excessively, you end up incurring charges. Storing only the reference and fetching the download link on demand seems a safer option to me.
- The most significant point for me was speed, especially with Cloud Functions. In my case, I needed to edit an image stored in Python Cloud Functions and then write the result image back into storage. Using the download link in the Cloud Function to fetch the image took 3000ms, whereas loading the image directly from storage using the reference only required 600ms.
So, I transitioned my entire project to use only the storage reference. I can retrieve the download link in my application as needed with getDownloadUrl(), eliminating the necessity to save both and saving memory. Additionally, updating a single value is simpler than managing two. These were my considerations when I switched from the download URL to the storage reference. I hope this provides some insights for you! :)
My Recommendation:
Instead of using .getDownloadUrl(), it's better to use .getData() directly.
For example, when displaying images, you might be tempted to use NetworkImage(downloadUrl) because it seems straightforward at first glance. However, this approach creates a long-lived URL, which can pose security risks. Additionally, if you only store the image reference, you'll have to await the URL every time, resulting in two calls for each image.
A more efficient and secure alternative is to use the getData() method. This method retrieves the data directly from the reference and also checks the security rules.