Uploading base64 to the firebase storage and getting back the download url

The first function called is addPostHandler, which is calling function storeImage. Inside storeImage function, postData.postImage is Array of string (Images converted into base64). What I am trying to do here is map all the images in postData.postImage and then upload it into the firestore, then get the download Url and push it into imageUrl. After I finish uploading all the images and getting the URL, at the end I want that console.log(“Printing….”) to run.

Error is storeImage function is returning empty string instead of downloadUrl.

const index = () => {
  const storeImage = async (postData: PostType) => {
    const imageUrl: string[] = [];
    const storage = getStorage();
    postData.postImage.map((image, i) => {
      const storageRef = ref(
        storage,
        `ImagesOfPosts/${postData.userId}/${postData.postId}/image ${i}`
      );
      uploadString(storageRef, image, "data_url", {
        contentType: "image/jpg",
      }).then(() => {
        getDownloadURL(storageRef)
          .then((result) => {
            imageUrl.push(result);
          })
          .catch((error) => {
            console.error(error);
          });
      });
    });

    console.log(imageUrl);

    return imageUrl;
  };

  const addPostHandler = async (enteredPostData: PostType) => {
    const imageUrl = await storeImage(enteredPostData);
    console.log("Printing......."); 
}

Answer

Your top-level code is not waiting until the upload and getting the download URL are finished, so you’re gonna see it return an empty array.

Since you’re uploading multiple images, you’ll need to use Promise.all() to only resolve storeImage when all image are done.

In total that’ll be something like:

const storeImage = async (postData: PostType) => {
  const storage = getStorage();
  const imageUrl = Promise.all(postData.postImage.map((image, i) => {
    const storageRef = ref(
      storage,
      `ImagesOfPosts/${postData.userId}/${postData.postId}/image ${i}`
    );
    return uploadString(storageRef, image, "data_url", {
      contentType: "image/jpg",
    }).then(() => {
      return getDownloadURL(storageRef);
    });
  });

  return imageUrl;
};