Search code examples
javascriptreactjsfirebase-realtime-databasefirebase-storage

React:"Why do uploaded pictures and information disappear after reloading the page?"


I am a beginner in React. I am making a Web App that uploads photos and can preview photos

I hope this code can upload the photo, the photo will be stored in Firebase Storage, and the photo information will also be stored in the Firebase database, photo and photo information can be displayed on the web page ,when I right-click and press delete, the photo will also deleted, when the page is reloaded, photos and information that have not been deleted will still be displayed.

But when I finished this code, I found that the photos can stored in Firebase Storage, and the photo informations are also stored in Firebase database, and both are displayed on the page, but when I reload the page, all will disappear . I found it I don't know where it is for a long time, so I would like to ask everyone, thank you guys!

I expect to be able to upload pictures and display them on the page. At the same time, the pictures will be stored in fireStorage, and the photo information will be stored in the firebase database. When I click the right button, it will show delete button and after pressing delete, the pictures will disappear directly. When the page reload, the page will have show those photos that were not deleted.

import { useState, useEffect } from "react";
 import {
  ref,
  uploadBytes,
  getDownloadURL,
  listAll,
  deleteObject,
} from "firebase/storage";
 import { db, storage } from "../utils/firebase";
 import {
  addDoc,
  collection,
  Timestamp,
  query,
  where,
  deleteDoc,
  getDocs,
} from "firebase/firestore";
 import { Image, Dropdown, Input } from "antd";
 import { AppstoreAddOutlined } from "@ant-design/icons";
 import { nanoid } from "nanoid";

 const items = [
  {
    label: "移除",
    key: "1",
  },
];

function UploadButton() {
  const [deleteImageRef, setImageUrls] = useState([]);
  const [originalImageUrls, setOriginalImageUrls] = useState([]);

  const handleImageUpload = (event) => {
    const imageUpload = event.target.files[0];
    if (imageUpload == null) return;
    const imageRef = ref(storage, `images/${imageUpload.name}`);
    uploadBytes(imageRef, imageUpload).then((snapshot) => {
      getDownloadURL(snapshot.ref).then((url) => {
        const file = {
          id: nanoid(),
          name: `${imageUpload.name}`,
          size: `${imageUpload.size}`,
          type: `${imageUpload.type}`,
          url: url,
          timestamp: Timestamp.now(),
        };
        setImageUrls((prev) => [...prev, file]);
        setOriginalImageUrls((prev) => [...prev, file]);
        const galleryCollectionRef = collection(db, "gallery");
        addDoc(galleryCollectionRef, file)
          .then(() => {
            console.log("File info added to Firestore");
          })
          .catch((error) => {
            console.error("Error adding file:", error);
          });
      });
    });
  };

  const deleteImage = async (url) => {
    console.log({ url });
    const galleryCollectionRef = collection(db, "gallery");
    const querySnapshot = await getDocs(
      query(galleryCollectionRef, where("url", "==", url))
    );
    querySnapshot.forEach(async (doc) => {
      await deleteDoc(doc.ref);
    });
    const imageRef = ref(storage, url);
    await deleteObject(imageRef);
    setImageUrls((prev) => prev.filter((image) => image.url !== url));
    setOriginalImageUrls((prev) => prev.filter((image) => image.url !== url));
  };

  useEffect(() => {
    const imagesListRef = ref(storage, `images/`);
    listAll(imagesListRef)
      .then((response) => Promise.all(response.items.map(getDownloadURL)))
      .then((url) => {
        setImageUrls(url);
        setOriginalImageUrls(url);
      })
      .catch((error) => console.log(error));
  }, []);

  const handleSearch = (value) => {
    if (value === "") {
      setImageUrls(originalImageUrls);
    } else {
      const filteredUrls = originalImageUrls.filter((url) =>
        url.toLowerCase().includes(value.toLowerCase())
      );
      setImageUrls(filteredUrls);
    }
  };

  return (
    <div className="upload-container">
      <div className="img-container-gallery">
        <Image.PreviewGroup className="upload-img">
          {deleteImageRef.map((image, index) => (
            <Dropdown
              menu={{
                items,
                onClick: async ({ key }) => {
                  if (key === "1") {
                    await deleteImage(image.url);
                  }
                },
              }}
              trigger={["contextMenu"]}
              key={index}
            >
              <span>
                <Image width={200} src={image.url} />
                <div>
                  <p>Name:{image.name}</p>
                </div>
              </span>
            </Dropdown>
          ))}
        </Image.PreviewGroup>
      </div>
      <div className="bottom-container">
        <div className="search-container">
          <Input.Search
            placeholder="Input text..."
            allowClear
            size="small"
            onSearch={handleSearch}
            onPressEnter={(e) => handleSearch(e.target.value)}
            onChange={(e) => {
              e.target.value && setImageUrls(originalImageUrls);
            }}
            className="search-input"
          />
        </div>
        <div className="button-container">
          <label
            htmlfor="file-upload"
            className="custom-upload-btn"
            onChange={handleImageUpload}
          >
            Upload Image
            <input type="file" id="file-upload" />
          </label>
          <div className="sort-btn-container">
            <button className="sort-btn">
              <AppstoreAddOutlined />
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
export default UploadButton;

Solution

  • In your useEffect you should get alll the photos from the api and then set them in state

    You'll map this state to image tags to show the photos If you cant see the images on reload you are not fetching and/or setting the images correctly.

    Check this part of the code:

      useEffect(() => {
        const imagesListRef = ref(storage, `images/`);
        listAll(imagesListRef)
          .then((response) => Promise.all(response.items.map(getDownloadURL)))
          .then((url) => {
            setImageUrls(url);
            setOriginalImageUrls(url);
          })
          .catch((error) => console.log(error));
      }, []);
    

    add console logs and see if images are being fetched and set accurately