Search code examples
node.jsfirebasegoogle-cloud-firestorexmlhttprequestfirebase-storage

Download file from firebase storage with HTTP request that anyone can download


I am attempting to download a file from a firebase storage bucket using a HTTP request.

bucket.file('<filepath>').getSignedUrl({
   action: 'read',
   expires: '03-17-2025'
})
.then((url: any) => {
   console.log(url);
   const xhr = new XMLHttpRequest();
   xhr.responseType = 'blob';
   xhr.onload = (event) => {
      xhr.response;
   };
   xhr.open('GET', url);
   xhr.send();
})
.catch((error) => {
      console.log(error);
});

However when I do this I get "Error: The caller does not have permission".

How do I make it so that anyone can download it with a link? I can worry about permissions and security later, this is just for testing.


Security Rules:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /<folder>/{allPaths=**} {
      allow read: if true; //allow anyone with link to read from the folder
      allow write: if request.auth != null;
    }
    match /{allPaths=**} {
      allow read, write: if request.auth != null; //all other locations are secured by auth
    }
  }
}

Solution

  • From the error message ("Error: The caller does not have permission") and the above comments (i.e. currently, your Storage security rules are allow read, write: if request.auth != null;), it appears that your security rules prevent the user to generate the signed URL with the getSignedUrl()method:

    So you should:

    • Either sign-in the user in such a way request.auth is not null.
    • Or adapt the Security Rules in order to allow unauthenticated users to read Objects in the bucket. Of course, this means that everybody can download these Objects, so it should probably be done only in a test environment.
    • Or implement any other adaptation that grants the user the read access to the desired Object.

    Note: Using allow read, write: if request.auth.uid != null in your Firestore or Cloud Storage security rules is usually not sufficient. As a matter of fact it is not difficult to get your Firebase config values from your app, therefore someone can easily use the Auth REST API to create an account in your Firebase project.