Home > OS >  Returning an image from Firebase storage within Reactjs
Returning an image from Firebase storage within Reactjs

Time:03-21

I have a function which goes off to retrieve an image from Firebase Storage:

import {
  getStorage,
  ref,
  getDownloadURL
} from 'firebase/storage';

const storage = getStorage();

export async function getImage(location) {
  const ImageURL = await getDownloadURL(ref(storage, location));
  return await ImageURL;
}

This is then called within a React component:

import { getImage } from 'API/Storage/getImage';

const EventPage = (props) => {
  return (
    <div>
      <img src={getImage('image.jpg')}
    </div>
  );
}

export default EventPage;

However the image doesn't display and instead shows: <img src="[object Promise]" alt="Show Image">

What's the best way of resolving the promise? Console logging ImageURL within the getImage function returns the URL as expected.

CodePudding user response:

You need to wait for the promise to resolve. You can fetch the data in a useEffect and store the value in a useState.

Here's a basic example:

import { getImage } from 'API/Storage/getImage';

const EventPage = (props) => {
  const [image, setImage] = useState();

  useEffect(async () => {
    const image = await getImage('image.jpg');
    setImage(image);
  }, []);

  return (
    <div>
      {image ? <img src={image} /> : "Loading image"}
    </div>
  );
}

export default EventPage;

The useEffect in the above example doesn't account for the case when your component is unmounted while still fetching the data. An implementation that accounts for that looks like so:

useEffect(() => {
  let wasUnmounted = false;
  getImage('image.jpg').then((image) => {
    if (wasUnmounted) return;
    setImage(image);
  });
  return () => {
    wasUnmounted = true;
  };
}, []);

Notice that the callback provided to useEffect isn't async. That's because async functions return a promise. To be able to detect that the component was unmounted we need to return a callback (it will be called when the component is unmounted, because of the empty array passed as a second argument). Please read more about useEffect here: https://reactjs.org/docs/hooks-reference.html#useeffect

  • Related