Firebase Storage:对象不存在图像上传路径错误

huangapple go评论65阅读模式
英文:

Firebase Storage: Object does not exist image upload path error

问题

以下是您要翻译的内容:

"I am getting an error every time I try to add and image to the firebase on the cloud.

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

The things is that the image it's being uploaded successfully on the storage but for whatever reason it can't be found and is not being added to the cloud.

What should I do?

This is my code:

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>
);
};

I can't seem to see how to get the path right...."

英文:

I am getting an error every time I try to add and image to the firebase on the cloud.

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

The things is that the image it's being uploaded successfully on the storage but for whatever reason it can't be found and is not being added to the cloud.

What should I do?

This is my code:

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

export const Shop = () =&gt; {
const [items, setItems] = useState([]);
const itemsRef = collection(db, &quot;items&quot;);

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

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

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

 const addItems = async (e) =&gt; {
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(() =&gt; {
  alert(&quot;Image uploaded&quot;);
}).catch((error) =&gt; {
  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(&quot;&quot;);
  setNewItemName(&quot;&quot;);
  setNewItemPrice(0);
} catch (err) {
  console.log(err);
}
};  

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

I can't seem to see how to get the path right....

答案1

得分: 1

问题出在你定义 Firebase 存储对象的 ref 方式上。在你的代码中,你使用了不推荐在 Firebase SDK 中使用的 gs:// URL 格式。你可以直接使用存储桶中图像的路径来引用图像。

你需要更改以下代码行:
const imageRef = ref(storage, `gs://cart-app-b469e.appspot.com/items/${newItemImage.name + v4()}`);

const imageRef = ref(storage, `items/${newItemImage.name + v4()}`);
这将将上传的对象存储到 items 文件夹,并使用 ${newItemImage.name + v4()} 作为文件名。

由于你立即获取下载URL:
const downloadURL = await getDownloadURL(imageRef);
但这段代码可能在上传文件代码之前运行,最好使用 async await 等待上传完成,如下所示:

  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);
  }
};```
也许在遵循上述代码后,downloadURL 将被检索并存储在 Firestore 文档中,没有任何错误。

参考链接: [**从 Blob 或文件上传**](https://firebase.google.com/docs/storage/web/upload-files#upload_from_a_blob_or_file)

<details>
<summary>英文:</summary>

The issue is with the way you are defining the ref for firebase storage objects. In your code, you&#39;re using a `gs:// URL` format, which is not recommended  using the Firebase SDK. You can directly reference the image using its path within the storage bucket.

You need to change the following line : 

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

To 

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

Which will store the uploaded object to the `items` folder with `${newItemImage.name + v4()}` as a file name.

As you are immediately getting the downloadURL with : 

const downloadURL = await getDownloadURL(imageRef);

But this code will have the possibility to run before the upload file code so it is better to wait for the upload to complete using async await as follows :

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);
}
};

May be after following above code downloadURL will be retrieved and stored in the Firestore document without any errors.

Reference : [**Upload from a Blob or File**](https://firebase.google.com/docs/storage/web/upload-files#upload_from_a_blob_or_file)

</details>



huangapple
  • 本文由 发表于 2023年5月22日 14:34:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76303541.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定