'Upload img to firebase storage + create new bucket

Self taught coder here. Hopefully I can explain this properly. I'm trying to create a recipe website where a user can upload their own custom recipe with images. The user submits a form and the info uploads to a database collection 'guides'. How does the file being uploaded to firebase storage send back a URL to react so that the form can record the URL into the steps array?

This is the logic for user to upload img in the form, inside Upload component:

    const uploadFile = () => {
      const name = new Date().getTime() + file.name
      const storageRef = ref(storage, file.name)

      const uploadTask = uploadBytesResumable(storageRef, file);

uploadTask.on('state_changed', 
  (snapshot) => {
    const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    console.log('Upload is ' + progress + '% done');
    setPercentage(progress)
    switch (snapshot.state) {
      case 'paused':
        console.log('Upload is paused');
        break;
      case 'running':
        console.log('Upload is running');
        break;
        default: 
          break;
    }
  }, 
  (error) => {
    console.log(error)
  }, 
  () => {
    // Handle successful uploads on complete
    getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
      setData((prev) => ({...prev, img: downloadURL}))
    });
  }
);

    }
    file && uploadFile();
  }, [file]);



Here is the logic to upload/submit form also inside the Upload component.


  const handleAddGuide = async (e) => {
    e.preventDefault();
    const newId = uuidv4()

    await setDoc(doc(db, "guides", newId), {
      author: e.target.author.value,
      categoryId: "100",
      categoryName: e.target.categoryName.value,
      // coverImg: imgURL,
      id: newId,
      name: e.target.name.value,
      tags: e.target.tags.value,
      steps: [
        {
          step: e.target.step.value,
          img: file.url <---- I need this file to upload to a folder inside storage named dynamically after the name of the recipe ("e.target.name.value").
        }
      ]
    });
  };

And this is where I initialize db and storage:


firebase.js 

import { initializeApp } from "firebase/app";
import { getFirestore } from 'firebase/firestore'
import { getAuth } from "firebase/auth";
import "firebase/storage"
import { getStorage } from "firebase/storage";

const firebaseConfig = {
  <details> 
}

const app = initializeApp(firebaseConfig);
export const userAuth = getAuth()
export const db = getFirestore(app)
export const storage = getStorage(app);


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source