Search code examples
firebasegoogle-cloud-platformgoogle-cloud-storagefirebase-storagefirebase-security

Firebase, file check, before making them public


I am building web platform where user can upload photos and videos, I use firebase storage for it, but I come a cross one problem that I cant solve.

I want to manually check all of the files before making them public.

So my first idea was to make to separate folder, and when admin account approve the file, he can move it from /private/img.jpg to /public/img.jpg. But for some reason, firebase storage doesn't have function to move files.

So I come with new idea to use custom metadata, to block to read images that doesn't have metadata visibility set to 'public'. But for me, this solution doesn't seems to be the best... and more you aren't able to block listing file with specific metadata, so even when the file is private, everybody can see that the file exist, and the name, and this is potential risk for me.

So are there anybody, who can help find new solution?

Thank you :)


Solution

  • Approach #1:

    You can use a Callable Cloud Function that you call from your app and which:

    1. Checks that the user who is calling has the Admin role (use a specific Custom Claim);
    2. If the user has the correct role, copies the file from the private "folder" to the public one (BTW see this answer on folders) by using the copy() method from the Google Cloud Storage Node.js SDK (which is the SDK to be used in a Cloud Function).

    Approach #2:

    Another totally different approach would be to take advantage of the new Cloud Storage Security Rules functionality which allows "building flexible permissions to protect access to storage files based on data within Firestore".

    With this functionality, you would be able to manage access to the files through Documents in Firestore. For each file in Cloud Storage, create a document in Firestore which has the same name as the file and contains a boolean field named (for example) published. By default, it is false and if the Admin approves the file you change it to true.

    The security rule would be along the following lines (untested):

    service firebase.storage {
      match /b/{bucket}/o {
        match /.../{fileId} {
          allow read: if 
            firestore.get(/databases/(default)/documents/files/$(fileId)).published
        }
      }
    }
    

    Don't forget to declare the correct Security Rules for the Firestore collection, in such a way only Admin users can approve files.