【问题标题】:How to upload images to Firebase web v9 using reactjs如何使用 reactjs 将图像上传到 Firebase web v9
【发布时间】:2021-12-11 15:09:33
【问题描述】:

我在将图像上传到 firebase 但使用网络版本 9 时遇到问题。 我正在关注他正在构建 facebook 克隆的一个平台上的教程。我被困在firebase上传图像和文件的这一部分...... 我检查了firebase的文档,并试图弄清楚应该更改,但我做不到。 我想要的是将firebase代码从旧版本转换为最新的web V9。 这是我的代码,但在以前的版本中:

import { useSession } from 'next-auth/client';
import { useRef, useState } from 'react';
import { db, storage } from '../firebase';
import firebase from 'firebase';

function InputBox() {
    const [session] = useSession();
    const inputRef = useRef(null);
    const filepickerRef = useRef(null);
    const[imageToPost, setImageToPost] = useState(null);

    const sendPost = (e) => {
        e.preventDefault();

        if (!inputRef.current.value) return;

        db.collection('posts').add({
            message: inputRef.current.value,
            name: session.user.name,
            email: session.user.email,
            image: session.user.image,
            timestamp: firebase.firestore.FieldValue.serverTimestamp()
        }).then(doc => {
            if (imageToPost) {
                const uploadTask = storage.ref(`posts/${doc.id}`).putString(imageToPost, 'data_url')

                removeImage();

                uploadTask.on('state_change', null, error => console.error(error), 
                () => {
                    //When the upload completes
                    storage.ref(`posts`).child(doc.id).getDownloadURL().then(url => {
                        db.collection('posts').doc(doc.id).set({
                            postImage: url
                        },
                        { merge: true}
                        );
                    });
                });
            }
        });

        inputRef.current.value = "";
    };

    const addImageToPost = (e) => {
        const reader = new FileReader();
        if (e.target.files[0]) {
            reader.readAsDataURL(e.target.files[0]);
        }
        reader.onload = (readerEvent) => {
            setImageToPost(readerEvent.target.result);
        };
    };

    const removeImage = () => {
        setImageToPost(null);
    };

    return (here is my jsx)

【问题讨论】:

    标签: reactjs firebase firebase-storage


    【解决方案1】:

    如果你的 firebaseConfig 没问题,那么这应该可以工作!

    import { setDoc, doc } from "firebase/firestore";
    import { ref, uploadString, getDownloadURL, getStorage  } from "firebase/storage";
    
                if (imageToPost) {
                    const storage = getStorage();
                    const storageRef = ref(storage, `posts/${docum.id}`);
                    const uploadTask = uploadString(storageRef, imageToPost, 'data_url');
    
                    uploadTask.on('state_changed', null,
                    (error) => {
                      alert(error);
                    },
                    () => {
                      getDownloadURL(uploadTask.snapshot.ref)
                      .then((URL) => {
                         setDoc(doc(db, "posts", docum.id), { postImage:URL }, { merge: true});
                      });
                    }
                  )
                  removeImage();
                };
    

    【讨论】:

    • 非常感谢,但现在它说“uploadTask 不是函数”
    • 改变这个:用uploadBytesResumable替换uploadString ==> const uploadTask = uploadBytesResumable(storageRef, imageToPost, 'data_url');
    【解决方案2】:

    2022 年更新=>

    import {
      ref,
      uploadBytesResumable,
      getDownloadURL,
      getStorage,
    } from "firebase/storage";
    
        const uploadPO = async (e) => {
            try {
              if (e.target.files && e.target.files[0]) {
                let reader = new FileReader();
                reader.onload = (e) => {
                  poImg.current = e.target.result;
                };
                const file = e.target.files[0];
                reader.readAsDataURL(file);
                setMessage("Uploading...");
                const storage = getStorage();
                const storageRef = ref(storage, `Erogon_Images/${file.name}`);
                const uploadTask = uploadBytesResumable(storageRef, file, "data_url");
        
                uploadTask.on(
                  "state_changed",
                  (snapshot) => {
                    const progress =
                      (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                    setMessage(`Upload is  ${progress}% done`);
                  },
                  (error) => {
                    // Handle unsuccessful uploads
                    throw error;
                  },
                  () => {
                    // Handle successful uploads on complete
                    // For instance, get the download URL: https://firebasestorage.googleapis.com/...
                    getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
                      const body = {
                        rfqID,
                        PO: downloadURL,
                      };
                      Api.post(PATH.updatePO,body).then(()=>{
                         setMessage("Uploaded Successfully");
                      }).catch(err => {
                          console.log(err)
                      })
                    });
                  }
                );
              }
            } catch (err) {
              console.log(err);
              poImg.current = null;
              setMessage("");
              notifyError(
                err?.message || "Something went wrong while uploading to storage"
              );
            }
          };
    

    【讨论】:

      【解决方案3】:

      其实一切都在documentation中详述。

      替换uploadTask 定义

      const uploadTask = storage.ref(`posts/${doc.id}`).putString(imageToPost, 'data_url')
      

      import { getStorage, ref, uploadString, getDownloadURL } from "firebase/storage";
      
      const storage = getStorage();
      const storageRef = ref(storage, `posts/${doc.id}`);
      
      const message = 'This is my message.';
      const uploadTask = uploadString(storageRef, imageToPost, 'data_url');
      

      并替换上传监控块,做

      import { doc, setDoc } from "firebase/firestore"; 
      
      uploadTask.on('state_changed',
        null
        (error) => {
          // ...
        }, 
        () => {
          getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
             setDoc(doc(db, "posts", doc.id), { postImage: url }, { merge: true});
          });
        }
      );
      

      请注意UploadTask object behaves like a Promise,并在上传完成时使用其快照数据解析,因此如果您只是对完整事件感兴趣,也可以使用uploadTask.then()

      【讨论】:

      • 非常感谢您的帮助。仍然再次显示此错误。TypeError: (0 , firebase_firestore__WEBPACK_IMPORTED_MODULE_6__.getStorage) is not a function
      • 检查 Firebase 的设置是否正确。 firebase.google.com/docs/web/setup
      • 我已经在使用 realtime-db 所以配置是 100% 正确的
      • 对不起,我不能再帮你了。此错误同时非常通用,并且非常依赖于您自己的配置。需要查看应用程序代码的大部分内容才能回答。
      【解决方案4】:

      我遇到了同样的错误,并且能够使用异步等待解决它。我知道这是一种正统的方法,但我能够让它发挥作用。

      我使用的逻辑与文档示例所具有的 Renaud Tarnec 相同,但我仍然认为 uploadTask 不是一个函数,很可能是一些异步问题。

      请看下面我的例子,你可以很容易地适应你的。

      请记住,我没有发现任何错误,但我建议您这样做。

      const sendPost = async () => {
          // I used uuid package to generate Ids
          const id = uuid();
          const storageRef = ref(storage, `posts/${id}`);
      
          // I await the uploadTast to finish
          const uploadTask = await uploadString(storageRef, cameraImage, 'data_url');
          
      
          //than get the url
          const url = await getDownloadURL(uploadTask.ref);
      
          //finally add the document to the DB
          await setDoc(
            doc(db, 'posts', id),
            {
              imageUrl: url,
              username: 'Apollo',
              read: false,
              //profilePic,
              timestamp: serverTimestamp(),
            },
            { merge: true }
          );
          
          navigate('/chats');
      
        };
      

      希望这对您或遇到相同问题的任何人有所帮助。

      【讨论】:

        【解决方案5】:

        我猜你正在观看 Sonny FB 克隆卡在新的 FB 更改中。这个版本适合我。

        import { collection, addDoc, serverTimestamp, doc, setDoc } from "firebase/firestore";
        import { getStorage, ref, uploadBytesResumable, getDownloadURL } from"firebase/storage";
          const sendPost = (e) => {
                e.preventDefault();
                if (!inputRef.current.value) return;
                // Add a new document with a generated id.
                addDoc(collection(db, "posts"), {
                    message: inputRef.current.value,
                    name: session.user.name,
                    email: session.user.email,
                    image: session.user.image,
                    timestamp: serverTimestamp(),
                }).then(docum => {
        
                    if (imageToPost) {
                        const storage = getStorage();
                        const storageRef = ref(storage, `posts/${docum.id}`);
                        const uploadTask = uploadBytesResumable(storageRef, imageToPost, "data_url");
                        removeImage();
                        uploadTask.on('state_changed', null,
                            (error) => {
                                console.log(error);
                            },
                            () => {
                                getDownloadURL(uploadTask.snapshot.ref)
                                    .then((URL) => {
                                        setDoc(doc(db, "posts", docum.id), { postImage: URL }, { merge: true });
                                    });
                            }
                        )
        
                    };
                });
                inputRef.current.value = ""
            }
        

        截至 2021 年 12 月 4 日,这项工作为我工作

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 2021-12-31
        • 2018-12-22
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 2021-08-11
        • 2022-01-12
        • 2021-12-16
        • 2021-12-12
        相关资源
        最近更新 更多