如何将文件上传到Firebase Storage并获取URL以保存在mongoDB数据库中

cbjzeqam  于 2023-08-04  发布在  Go
关注(0)|答案(1)|浏览(121)

我正在创建一个基于后的应用程序,用户可以张贴图片和文字。我想保存Firebase存储桶上的图像,并立即获得图像链接,并将图像和照片描述文本存储到我的数据库
我正在使用Node、Express和Mongo DB。下面是我的代码

import ModalStyles from "./_createpost.module.scss";
import {
    ref,
    uploadBytes,
    getDownloadURL
} from "firebase/storage";
import { storage } from "../../../config/firebaseConfig";
import { faCamera, faPhotoFilm } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useContext, useEffect, useState } from "react";
import UserContext from "../../../context/userContext";
import { uuid } from "uuidv4";
import { v4 } from "uuid";
import axios from "axios";


interface IModalProps {
}

const Modal = ({ }: IModalProps) => {
    const user = useContext(UserContext)
    const [imageUpload, setImageUpload] = useState<FileList | null>({} as FileList);
    const [postDesc, setPostDesc] = useState<string>('');
    const [imageUrls, setImageUrls] = useState<Array<string>>([]);

    const convertToBlob = (file: File): Promise<Blob> => {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onloadend = () => {
                const blob = new Blob([reader.result as ArrayBuffer], { type: file.type });
                resolve(blob);
            };
            reader.onerror = reject;
            reader.readAsArrayBuffer(file);
        });
    };

    const uploadImages = async () => {

        if (!imageUpload) return;

        let promises: string[] = [];

        for (let index = 0; index < imageUpload.length; index++) {
            /* 
            const { name, type } = imageUpload[index];
            const file = new File([name], name, { type: type });
            const blob = await convertToBlob(file); 
            */
            const blob = await convertToBlob(imageUpload[index]);

            const imageRef = ref(storage, `images/${imageUpload[index].name + v4()}`);

            uploadBytes(imageRef, blob).then((snapshot) => {
                getDownloadURL(snapshot.ref).then((urls) => {
                    console.log(urls);
                    
                    promises.push(urls)
                    setImageUrls(prev => [...prev, urls]);
                });
            }).catch(err => console.log('An Error Occured!', err))
        }

        return promises;
    };

    const uploadFile = async (e: React.FormEvent) => {
        e.preventDefault();

        const imgs = uploadImages();
        console.log(imgs);
    
        if (!imgs) return;
           try {
               const response = await axios.post(`http://localhost:5000/post/create`, { creator_id: "64af540d576b8737651135a4", post_description: postDesc, photos: imgs });
               if (response.data) console.log('image uploaded successfully');
     
           } catch (error) {
               console.log('An Error occured while uploading the post');
     
           } 

    }
    const onchange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const files = event.target.files;
        setImageUpload(files);

    }

    return <div className={ModalStyles.modal__container}>
        <h4 className={ModalStyles.modal__title}>Create Post</h4>
        <div className={`divider ${ModalStyles.modal__divider}`}></div>

        <div>
            <div className={`${ModalStyles.post__post_header} mt-1`}>
                <img src={user.profilePixs} className={ModalStyles.post__user_pixs} alt={user.firstname} />
                <div className={ModalStyles.post__post_info}>
                    <p className={ModalStyles.post__user_name}>{user.firstname} {user.lastname}</p>
                    <p>Public</p>
                </div>
            </div>
            <form className={ModalStyles.modal__post_inputField} onSubmit={uploadFile}>
                <textarea name="post_desc" id="post_desc" className={ModalStyles.modal__description} value={postDesc} onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setPostDesc(e.target.value)}></textarea>
                <div className={`divider ${ModalStyles.modal__divider}`}></div>
                <p className={ModalStyles.modal__addPhotoText}>
                    <span>  Add to your Post</span>

                    <FontAwesomeIcon icon={faPhotoFilm} size="2xl" className={ModalStyles.modal__addPhotoIcon} />
                    <input type="file" name="photo" id="photo" multiple onChange={onchange} accept="image/png, image/jpeg" className={ModalStyles.modal__addPhotoIcon} />

                </p>
                <input type="submit" value="Post" className={ModalStyles.modal__submitBtn} />
            </form>
        </div>
    </div>;
};

export default Modal;

字符串
它总是从Promise返回一个空的图像数组。
然后在发送和空数组到我的数据库,网址是返回。我知道这是由于异步功能,但我不能数字如何使fininsh的第一个请求之前,下一个,因为我希望的网址是可用的,然后才作出下一步行动
尝试了上面的代码,但没有前进的道路

xzv2uavs

xzv2uavs1#

这是我后来决定的,它的工作,但我觉得混合,然后和尝试/捕捉不相关。
下面是我的代码

const uploadPost = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!imageUpload) return;
    let postURLs: string[] = [];

    //Check if the image selected is NOT LESS THAN 2 or GREATER THAN 6
    if (imageUpload.length >= 2 && imageUpload.length <= 6 && (postDesc !== "")) {
        try {
            //Loop through FileList and upload each image to the Firebase Bucket
            for (let index = 0; index < imageUpload.length; index++) {
                const blob = imageUpload[index];
                const imageRef = ref(storage, `images/${imageUpload[index].name + v4()}`);

                await uploadBytes(imageRef, blob).then(async snapshot => {
                    await getDownloadURL(snapshot.ref).then((urls) => {
                        postURLs.push(urls);//Push each image url uploaded 
                    })
                })
            }
            const payload = { creator_id: "64af540d576b8737651135a4", post_description: postDesc, photos: postURLs };

            const response = await axios.post(`http://localhost:5000/post/create`, payload);

            if (response.data) toast.success(response.data.message);
        } catch (error) {
            toast.error('An Error Occured while Uploading  your Post');
        }
    }
    toast.error('Photos must be Greater than 2 and less than 6')
}

字符串
应该有人帮我重构它,这样一切都可以在一个try/catch块中

相关问题