无法在React Js的同一个firestore文档中添加firebase存储下载URL

tzcvj98z  于 2023-02-19  发布在  React
关注(0)|答案(1)|浏览(123)

我尝试上传多张图片到firebase存储器,并将这些网址作为字符串数组存储在一个firestore文档中,但我无法将所有网址添加到同一个firestore文档中,而是为每个firebase存储器网址创建不同的文档。
ImageUpload.js

import React, { useState } from "react";
import { toast } from "react-toastify";
import { db, storage } from "../firebase.config";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import {collection ,addDoc ,arrayUnion ,FieldValue ,updateDoc} from "firebase/firestore";
import { useNavigate } from "react-router-dom";
import "./style.css";

function ImageUpload() {
  const [allImages, setAllImages] = useState([]);

  function handleAllImage(e) {
    e.preventDefault();
    setAllImages(e.target.files);
    console.log(e.target.files);
  }

  function MutipleUpload(e) {
    e.preventDefault();

    try {
      const docRef = collection(db, "products");

      {
        for (let i = 0; i < allImages.length; i++) {

          const storageRef = ref(storage, `productImages/${allImages[i].name}`);
          const uploadTask = uploadBytesResumable(storageRef, allImages[i], {
            contentType: allImages[i].type,
          });

          uploadTask.on(
            "state_changed",
            (snapshot) => {
              const progress =
                (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
              console.log(progress);
            },
            (error) => toast.error(error.message),
            () => {
              getDownloadURL(uploadTask.snapshot.ref).then(
                async (downloadURL) => {
                  await addDoc(docRef, {
                    imgUrl: arrayUnion(downloadURL),
                  });
                }
              );
            }
          );
        }
      }
      toast.success("product added successfully!");
      
    } catch (error) {
      console.log(error.message);
    }
  }

  return (
    <>
      <input
        type="file"
        multiple="multiple"
        onChange={handleAllImage}
        required
      />
      <button onClick={MutipleUpload} type="submit" className="buy__btn mt-3">
        Add Image
      </button>
    </>
  );
}

export default ImageUpload;

额外的文本导致错误“看起来你的帖子大部分是代码;请补充一些细节。”

waxmsbnn

waxmsbnn1#

问题出在以下代码中:

getDownloadURL(uploadTask.snapshot.ref).then(
  async (downloadURL) => {
    await addDoc(docRef, {
      imgUrl: arrayUnion(downloadURL),
    });
  }
);

每次调用addDoc时,Firestore都会在集合中创建一个新文档。
如果要更新现有文档,则必须:
1.记住要更新的文档的文档ID。
1.然后对该文档调用updateDoc
要生成一个文档ID,然后一直更新它,请查看文档中有关添加文档的第三个代码片段:
在某些情况下,使用自动生成的ID创建一个文档引用,然后在以后使用该引用可能会很有用。对于此用例,您可以调用doc():

import { collection, doc, setDoc } from "firebase/firestore"; 

// Add a new document with a generated id
const newCityRef = doc(collection(db, "cities"));

// later...
await setDoc(newCityRef, data);

应用到您的用例中,可能看起来 * 像 * 这样:

const docRef = collection(db, "products");
const newDocRef = doc(docRef); // 👈 generate reference to a single new doc

{
  for (let i = 0; i < allImages.length; i++) {
    const storageRef = ref(storage, `productImages/${allImages[i].name}`);
    const uploadTask = uploadBytesResumable(storageRef, allImages[i], {
      contentType: allImages[i].type,
    });

    uploadTask.on(
      "state_changed",
      (snapshot) => {
        const progress =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log(progress);
      },
      (error) => toast.error(error.message),
      () => {
        getDownloadURL(uploadTask.snapshot.ref).then(
          async (downloadURL) => {
            await setDoc(newDocRef, { // 👈 Call setDoc, since the doc may not exist yet
              imgUrl: arrayUnion(downloadURL),
            }, { merge: true }); // 👈 tell it to merge values into any existing doc
          }
        );
      }
    );
  }
}

相关问题