每次我try 到云上的 firebase 基地addimage时,我都会得到一个错误.

FirebaseError: Firebase Storage: Object 'items/Screenshot at May 22 07-33-37.png9573dc82-ec43-4789-88ec-e93727d6a11f' does not exist. (storage/object-not-found)

问题是,它被成功上传到存储上的图像,但无论出于什么原因,它都找不到,也没有被添加到云中.

我该怎么办?

这是我的代码:

import React, { useState, useEffect } from 'react';
import { db, storage } from './../../config/config';
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
import { getDocs, collection, addDoc } from 'firebase/firestore';
import { ItemsList, AddForm } from './shopStyle';
import { v4 } from 'uuid';

export const Shop = () => {
const [items, setItems] = useState([]);
const itemsRef = collection(db, "items");

 // New item states
const [newItemName, setNewItemName] = useState("");
const [newItemPrice, setNewItemPrice] = useState(0);
const [newItemImage, setNewItemImage] = useState("");

  useEffect(() => {
    const fetchData = async () => {
    try {
    const data = await getDocs(itemsRef);
    const filteredData = data.docs.map((doc) => ({
      ...doc.data(),
      id: doc.id,
    }));
    setItems(filteredData);
  } catch (err) {
    console.error(err);
  }
};
fetchData();
 }, []);

  function handleImage(e) {
e.preventDefault();
let pickedFile;
if (e.target.files && e.target.files.length > 0) {
  pickedFile = e.target.files[0];
  setNewItemImage(pickedFile);
  console.log(pickedFile);
}
}

 const addItems = async (e) => {
e.preventDefault(); // Prevent form submission

if (newItemImage == null) return;

const imageRef = ref(storage, `gs://cart-app-b469e.appspot.com/items/${newItemImage.name + v4()}`);
uploadBytes(imageRef, newItemImage).then(() => {
  alert("Image uploaded");
}).catch((error) => {
  console.log(error);
});

try {
  const downloadURL = await getDownloadURL(imageRef);

  const newItem = {
    Image: downloadURL,
    Name: newItemName,
    Price: newItemPrice,
  };

  await addDoc(itemsRef, newItem);

  // Clear input fields after successful addition
  setNewItemImage("");
  setNewItemName("");
  setNewItemPrice(0);
} catch (err) {
  console.log(err);
}
};  

  return (
<div>
  <AddForm onSubmit={addItems}>
    <input
      accept="image/*"
      id="icon-button-file"
      type="file"
      onChange={handleImage}
    />
    <input
      type="text"
      placeholder="name"
      value={newItemName}
      onChange={(e) => setNewItemName(e.target.value)}
    />
    <input
      type="number"
      placeholder="price"
      value={newItemPrice}
      onChange={(e) => setNewItemPrice(e.target.value)}
    />
    <button onClick={addItems}>Add</button>
  </AddForm>
  <ItemsList>
    {items.map((item) => (
      <div key={item.id}>
        <img src={item.Image} alt={item.Name} />
        <h1>{item.Name}</h1>
        <h4>{item.Price}</h4>
      </div>
    ))}
  </ItemsList>
</div>
);
};

我似乎不知道怎么才能走对这条路……

推荐答案

问题出在您定义Firebase存储对象的引用的方式上.在您的代码中,您使用的是gs:// URL格式,使用Firebase SDK时不推荐使用这种格式.您可以通过镜像在存储桶中的路径直接引用该镜像.

您需要更改以下行:

const imageRef = ref(storage, `gs://cart-app-b469e.appspot.com/items/${newItemImage.name + v4()}`);

const imageRef = ref(storage, `items/${newItemImage.name + v4()}`);

其将上载的对象存储到文件名为${newItemImage.name + v4()}items文件夹.

因为您可以通过以下命令立即获得下载URL:

const downloadURL = await getDownloadURL(imageRef);

但此代码可能会在上载文件代码之前运行,因此最好使用异步等待来等待上载完成,如下所示:

const addItems = async (e) => {
  e.preventDefault(); 
  if (newItemImage == null) return;
  const imageRef = ref(storage, `items/${newItemImage.name + v4()}`);
  try {
    await uploadBytes(imageRef, newItemImage);
    alert("Image uploaded");
    const downloadURL = await getDownloadURL(imageRef);
    const newItem = {
      Image: downloadURL,
      Name: newItemName,
      Price: newItemPrice,
    };
    await addDoc(itemsRef, newItem);
    setNewItemImage("");
    setNewItemName("");
    setNewItemPrice(0);
  } catch (err) {
    console.log(err);
  }
};

可能是在遵循上述代码下载后,URL将被检索并存储在FiRestore文档中,没有任何错误.

参考文献:Upload from a Blob or File

Reactjs相关问答推荐

Firebase删除UserWithEmail AndPassword仅创建匿名用户

从app.js导航,这是在BrowserRouter包装之外

客户端组件中服务器组件的两难境地

Reaction路由的问题-在Effect使用API调用响应设置状态之前呈现页面

如何在react组件中使用formik进行验证

单击按钮时在子元素中不显示任何内容-react

在react.js的条形图中获取错误&unfined是不可迭代的

使用useReducer时,props 未从父级传递给子或孙级

有没有一种惯用的方式来接受特定的子元素?

使用`Link`包装`tr`标记会在Next.js中产生水合错误14

如何在与AntD的react 中限制文件上传和显示消息?

在Reaction中管理多个状态

useRef()的钩子调用无效

在一个事件处理程序中进行多次调度是个好主意吗?

React:如何使用条件渲染和react 挂钩来更新另一个组件的状态?

从 React 应用程序调用未经身份验证的 graphql 查询时出现错误:没有当前用户

React CSSTransition 两次创建新页面并在这两个相同的页面上运行转换

react 事件顺序

如何通过 Material ui select 使下拉菜单下拉

Material UI 安装和 React v. 18.2 出现问题