2
votes

I'm creating a dating React web app where users can upload pictures of themselves to their user profile. I want to use Firebase storage. I want to protect the images so that they are only viewable when accessing from my web app by authenticated users - right now I get an image like this:

  let storageRef = firebase.storage().ref(`images/${userid}/${userImageName}`);

// Get the download URL
storageRef.getDownloadURL().then(function(url) {
    // Insert url into an <img> tag to "download"
})

This is great - but once I put the URL in the src attribute in the image tag anyone who views the source code can copy the URL and send it via email, text message, etc., making it "public". I have tried uploading images in base64 string using the putString() function also only for Firebase storage to yet again create a URL for it like a normal image upload when using the put() function.

So my question is - can I use Firebase Storage to store images and make them "private" so that only authenticated users of my web app are able to view them? Is there a way to get only the image data and use that to generate the images in the frontend/client so that no actual URLs are ever placed in the JS code?

1

1 Answers

2
votes

The call to getDownloadURL() is protected by Security Rules, which means that if you write a rule like:

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{userId}/{userImageName} {
      // any authenticated user can read the bytes or get a download URL
      allow read: if request.auth != null;
      // only the given user can upload their photo
      allow write: if request.auth.uid == userId;
    }
  }
}

They will not allow unauthenticated people to download URLs.

As for the second issue: once someone can see a file, assume that they have already downloaded/screenshotted it and can share it, even if the URL isn't publicly accessible (or even on the page). Viewing something is equivalent to downloading it, so there's really no difference where it's coming from as the end result can be the same.