Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Firebase doc field shows an empty array after using useState()

I’m new to react and I’m trying to make an app, where user can upload multiple images at once, and those images get sent to the firebase storage, and urls of those images get stored in an array inside a doc, so that later on they can be accessed in a different page.

Here is a snippet of my code:

function CreateCarParts({isAuth}) { 
    const [images, setImages] = useState(null); 
    const [imageUrls, setImageUrls] = useState([]);
    
    let navigate = useNavigate();
    
    const postsCollectionRef = collection(db, "CarParts")
    
    useEffect(() => {
        if (!localStorage.getItem('isAuth')){
            navigate("/login");
        };
    }, []);
    
    const uploadImages = async () => {
        if(images === null) return;
        let uniqueFolderName = new Date().getTime().toString();
        const imageList = Array.from(images);
        for(let i = 0; i < imageList.length; i++) {
            const image = imageList[i];
            const imageLinkName = `carParts/${uniqueFolderName}/${image.name}`;
            const imageRef = ref(storage, imageLinkName);
            const snapshot = await uploadBytes(imageRef, image);
            const url = await getDownloadURL(snapshot.ref);
            setImageUrls((prev) => [...prev, url]);
        }
        alert("Images Uploaded");
    };
    
    const createPost = async () => {
        await uploadImages();
        await addDoc(postsCollectionRef, {imageUrls});
        navigate('/carparts');
    };
    return ( 
            <>
                <Form.Control onChange={(event) => {setImages(event.target.files);uploadImages();}} type="file" multiple />
    
                <Button onClick={createPost}> Submit </Button>
    
            </>
        ) 
}
export default CreateCarParts;

The images get sent to the storage, and the doc is created successfully, however the imageUrls array is empty. I can’t figure out why it’s not working, I assume I’m using the useState() incorrectly.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

imageUrls won’t be updated in the same render cycle, so calling await addDoc(postsCollectionRef, {imageUrls}); right after await uploadImages(); won’t work

I would store urls in a local array instead

function CreateCarParts({isAuth}) { 
    const [images, setImages] = useState(null);
    
    let navigate = useNavigate();
    
    const postsCollectionRef = collection(db, "CarParts")
    
    useEffect(() => {
        if (!localStorage.getItem('isAuth')){
            navigate("/login");
        };
    }, []);
    
    const uploadImages = async () => {
        if(images === null) return;
        let uniqueFolderName = new Date().getTime().toString();
        const imageList = Array.from(images);
        const urls = [];
        for(let i = 0; i < imageList.length; i++) {
            const image = imageList[i];
            const imageLinkName = `carParts/${uniqueFolderName}/${image.name}`;
            const imageRef = ref(storage, imageLinkName);
            const snapshot = await uploadBytes(imageRef, image);
            const url = await getDownloadURL(snapshot.ref);
            urls.push(url);
        }
        alert("Images Uploaded");
        return urls;
    };
    
    const createPost = async () => {
        const imageUrls = await uploadImages();
        await addDoc(postsCollectionRef, {imageUrls});
        navigate('/carparts');
    };
    return ( 
            <>
                <Form.Control onChange={(event) => {setImages(event.target.files);uploadImages();}} type="file" multiple />
    
                <Button onClick={createPost}> Submit </Button>
    
            </>
        ) 
}
export default CreateCarParts;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading