Search code examples
pythonflutterfirebasegoogle-cloud-firestorefirebase-storage

Get url after uploading file to Firebase Storage


I am developing a Flutter application that reads from a Firestore database and Firebase Storage. The Firebase Storage read rules are set to allow only authenticated users. I also have a Python script that uploads content to Firebase Storage and updates Firestore with the relevant file URLs.

Here is the uploading snippet

    def _upload_file(self, file_path: str, storage_path: str) -> str:
        blob = self.bucket.blob(storage_path)
        blob.upload_from_filename(file_path)
        return blob.public_url

however the urls generated by that result in a 403 (even by the authenticated user of the application and also if the rules of the storage are set to always read and write).

Problem: I need to generate URLs for the uploaded files that can be stored in Firestore and accessed by the Flutter application. Here are the approaches I have tried and their issues:

blob.public_url as said before, results in a 403 error in Flutter even if the user is authenticated.

generate_signed_url() Not suitable as it expires after 7 days.

blob.make_public() Works in Flutter but bypasses security rules, posing a security risk (it makes the url work from everywhere even if the rules are set to allow read only from authenticated users).

Additional Info In a previous flutter application I developed, I had to do the upload of the content from the app itself and the code in dart was working fine generating the correct url

Future<String> uploadUserImage(File image, String uid) async {
    final String fileName = uid + ".jpg";
    final ref =
        _storage.ref().child(StorageCollections.userImages).child(fileName);
    await ref.putFile(image);
    return await ref.getDownloadURL();
  }

// generates this url: https://firebasestorage.googleapis.com/v0/b/xxxxx/o/userImages%xxxxx.jpg?alt=media&token=xxxxxx

However i can't seem to achieve the same result in Python.

Question

How can I get, after the upload of a file, a correct url that works with Storage rules and doesn't expire with the module firebase_admin (or other ways)?


Solution

  • If you want to be able to set security rules to control access to the data, you should not be using a download URL or signed URL, as both of those bypass the security rules.

    Instead, write either the gs:// URL or the relative path of the image to the database, create a reference based on that in your client-side code (potentially using refFromURL), and then use the SDK methods to download the data to memory or a local file.