How to get reusable url for a picture in firebase storage that has a known path?

Viewed 627

I upload all my users profile photos in this path:

    const userUploadRef = ref(
      storage,
      `profilePhotos/${user.data?.uid}`
    );

I currently access the url like this:

  getDownloadURL(uploadTask.snapshot.ref).then(async (downloadUrl) => {
          if (user.data?.uid) {
            setDownloadURL(downloadUrl);

However, I just realized that even though the path is always going to be the same, each picture has a different url?

This causes massive issues - if I want to attach this user photo to something like comments, posts or any other content, I will have to make sure that the user profile image url is updated.

Surely there must be a way that I can reuse the same url since the path to the user profile photo is always going to be the same regardless?

Edit:

I have tried following this guide - https://www.sentinelstand.com/article/guide-to-firebase-storage-download-urls-tokens on how to remove the token and make my file public, but firebase keeps adding the token regardless.

        if (folder == "profilePhotos" && isThumbnail) {
          const [newFile]: any = file.makePublic();
          const [metadata] = newFile.getMetadata();
          const url = metadata.mediaLink;

          const userPublicRef = db.collection("usersPublic").doc(userId);
          const usersPrivateRef = db.collection("users").doc(userId);
1 Answers

If the photos are public, once you have uploaded them to Firebase storage, just do not pass the download token and that will achieve what you want (this is not a Firebase supported use).

The download of the URL will have the following format firebasestorage.googleapis.com/XXX?alt=media&token=YYY and the part that's changing is the token generated, you can remove this if the security rules allow anonymous access.

Here is a good website that can help you.

1st answer edition:

These are the rules that I used in Firebase storage:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read: if true; 
      allow write: if false;
    }
  }
}

By using these rules, the token is no longer needed and can be accessed by anyone, but you still need to remove the token from the URL manually

For example, here is the complete URL with the token:

https://firebasestorage.googleapis.com/v0/b/my-firebase-application-92719.appspot.com/o/istockphoto-496152924-612x612.jpg?alt=media&token=960c993e-dc2b-483f-ae30-5c4eeb8c1e73

You’ll need to delete after &token and you’ll get:

https://firebasestorage.googleapis.com/v0/b/my-firebase-application-92719.appspot.com/o/istockphoto-496152924-612x612.jpg?alt=media

Now I can access the picture without the need of the token of the test picture I created:

https://firebasestorage.googleapis.com/v0/b/my-firebase-application-92719.appspot.com/o/istockphoto-496152924-612x612.jpg?alt=media

I would like to highlight that this is not a recommended security setting because now everything in the URL can be accessed by anyone.

Related