skip to Main Content

I’m probably missing something simple. I have been stuck on this for a while and its critical. Any assistance would be appreciated.

I have a firestore storage database with rules that allow everyone to read(see) images.

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /images/{userId} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.uid == userId;
    }
    match /videos/{userId} {
      allow read: if true
      allow write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

Yet when i refresh a particular page, i get a:

Uncaught (in promise) FirebaseError: Firebase Storage: User does not have permission to access 'images/BJBAPfJMTCOq9OypfdkZ9z1NtQ93'. (storage/unauthorized)

The code to list all images belonging to a specific user:

export default function MultiMedia({ handleUser }) {
  const imageListRef = useRef(ref(storage, `images/${handleUser}`));
  const [imageList, setImageList] = useState([]);

  useEffect(() => {
    listAll(imageListRef.current).then((response) => {
      response.items.forEach((item) => {
        getDownloadURL(item).then((url) => {
          setImageList((prev) => [...prev, url]);
        });
      });
    });
  }, []);

  return...

The confusion is that images do render on a different page, the home page which pulls from a firestore database that has images url and uid as fields, amongst other fields.

export default function ImageGallery() {
  const [imageData, setImageData] = useState([]);

  useEffect(() => {
    async function reloadHome() {
      try {
        const querySnapshot = await getDocs(collection(db, "images"));

        querySnapshot.forEach((doc) => {
          setImageData((prevValue) => {
            return [
              ...prevValue,
              { imageURL: doc.data().imageURL, user: doc.data().user },
            ];
          });
        });
      } catch (error) {
        console.log(error);
      }
    }
    reloadHome();
  }, []);

Firestore security for images folder:

rules_version = '2';
service cloud.firestore {
    match /images/{image} {
    allow read: if true;
      allow create: if isLoggedIn();
      allow update, delete: if isLoggedIn() && request.auth.uid == resource.data.user;
    }
}

I would expect the storage security rules that would prevent a user from seeing an image on a user profile pulled from Firebase storage would be the same rule that would prevent the same user from seeing the same image who’s download URL was stored in a Firestore database.

2

Answers


  1. Since you are using listAll() on users/{userId}, I assume there are multiple files under that prefix and it’s not a single object. In that case, you must specify rules for objects within that prefix and just that path that you doing now. For example, you current rules will allow reading an object images/user1.png. Try using a recursive wildcard as shown below:

    match /images/{userId}/{file=**} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.uid == userId;
    }
    

    Additionally, instead of updating the state in every iteration of the loop, you can update it only once like this:

    useEffect(() => {
      listAll(imageListRef.current).then(async (response) => {
        const promises = response.items.map((item) => getDownloadURL(item));
        const urls = await Promise.all(promises);
        setImageList(urls);
      })
    }, []);
    
    Login or Signup to reply.
  2. if you have set the rule allow read: if true; and are still seeing read permission errors when trying to read from firebase storage, there are several things you can check:

    1. make sure that you are authenticated: if your firebase storage security rules require authentication to access certain data, it’s important to make sure that you are authenticated before attempting to access that data. you can check if you are authenticated by calling the firebase.auth().currentuser method in your client-side javascript code.

    2. check the firebase storage bucket you are trying to access: if you have multiple firebase storage buckets, make sure that you are using the correct bucket name in your code. you can check the name of a firebase storage bucket by going to the firebase console, navigating to your project, and selecting the “storage” option in the left-hand menu.

    3. check your code for errors: make sure that your client-side javascript code is not producing any errors that could be preventing your firebase storage rules from working properly. you can use your web browser’s developer tools to check for errors in your code.

    4. check if firebase storage is configured to use custom domain names: if you are using custom domain names with firebase storage, make sure that your dns records are set up properly and pointing to the correct firebase storage bucket.

    5. try clearing your cache and cookies: if you are still having issues with firebase storage access, try clearing your web browser cache and cookies.

    if none of these solutions work, you may need to check your firebase

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search