資料刪除

deleteDoc()

import { doc, deleteDoc } from "firebase/firestore";

await deleteDoc(doc(db, "cities", "DC"));

在firestore裡,利用deleteDoc去刪除文件時,需要document的id,要先取得id,接下來把document的id傳到deleteDoc裡。

我們在讀取documents的時候,也要讀取document的id。

資料修改

可以利用setDoc()去修改資料,當文件不存在時,setDoc()會新增文件,當文件存在時,文件內容會改變

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

// Add a new document in collection "cities"
await setDoc(doc(db, "cities", "LA"), {
  name: "Los Angeles",
  state: "CA",
  country: "USA"
});

<aside> 📢 setDoc()如果只有傳一個欄位,整個文件就會只有一個欄位,除非加上{merge: true}

</aside>

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

const cityRef = doc(db, 'cities', 'BJ');
await setDoc(cityRef, { capital: true }**, { merge: true }**);

也可以利用updateDoc()去修改資料

<aside> 📒 updateDoc()如果只有傳一個欄位,整個文件就會只有一個欄位被修改

</aside>

import { doc, updateDoc } from "firebase/firestore";

const washingtonRef = doc(db, "cities", "DC");

// Set the "capital" field of the city 'DC'
await updateDoc(washingtonRef, {
  capital: true
});

根據上面的範例,新增deleteProduct、updateProduct,回傳時,移除不需要的setProducts。

/app/product/useProduct.tsx

import { addDoc, collection, deleteDoc, doc, getDocs, getFirestore, orderBy, query, updateDoc } from "firebase/firestore";
import app from "@/app/_firebase/config"
import { useEffect, useState } from "react";

export default function useProducts() {
  const db = getFirestore(app);
  const [products, setProducts] = useState<{ desc: string, price: number }[]>([
  ])
  const [updated, setUpdated] = useState(0);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    async function fetchData() {
      setIsLoading(true);
      let data: { desc: string, price: number }[] = [];
      const productRef = collection(db, "product")
      const productQuery = query(productRef, orderBy("price"));
      const querySnapshot = await getDocs(productQuery);
      querySnapshot.forEach((doc) => {
        data.push({ desc: doc.data().desc, price: doc.data().price })
        console.log(`${doc.id} => ${doc.data()}`);
      });
      setProducts(() => [...data]);
      setIsLoading(false);
    }
    fetchData();
  }, [db, updated]);

  async function addProduct(product: { desc: string, price: number }) {
    const db = getFirestore(app);
    const docRef = await addDoc(collection(db, "product"),
      { desc: product.desc, price: product.price });
    console.log("Document written with ID: ", docRef.id);
    setUpdated((currentValue) => currentValue + 1)
  }

  async function deleteProduct(id: string) {
    try {
      const db = getFirestore(app);
      **await deleteDoc(doc(db, "product", id));**
      setUpdated((currentValue) => currentValue + 1)
    }
    catch (error) {
      console.error(error);
    }

  }
  async function updateProduct(product: { id: string, desc: string, price: number }) {
    try {
      const db = getFirestore(app);
      **await updateDoc(doc(db, "product", product.id),
        { desc: product.desc, price: product.price });**
      setUpdated((currentValue) => currentValue + 1)
    }
    catch (error) {
      console.error(error);
    }

  }

  return [products, addProduct, deleteProduct, updateProduct, isLoading] as const;

}

打開ProductList.tsx,首先,因為回傳值改變了,要修改以下內容:

const [products, addProduct, **deleteProduct,** **updateProduct,** isLoading] = useGetProducts();