新增資料可以利用addDoc(),在collection裡(如:user)新增文件內容,這個方式不需要提供doc id,firestore會自動產生doc id
import { collection, addDoc } from "firebase/firestore";
// Add a new document with a generated id.
const docRef = await addDoc(collection(db, "cities"), {
name: "Tokyo",
country: "Japan"
});
console.log("Document written with ID: ", docRef.id);
新增資料也可以利用setDoc(),在collection裡(如:user)更新文件內容,跟addDoc()不同的是需要提供id,當id不存在時,會利用id為doc id產生一個新的文件
import { doc, setDoc } from "firebase/firestore";
await setDoc(doc(db, "cities", "new-city-id"), data);
我們參考上面的範例,來修改一下我們上週的程式。
/app/product/useProduct.tsx
import { addDoc, collection, getDocs, getFirestore } 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 }[]>([
{ desc: "iPad", price: 20000 },
{ desc: "iPhone 8", price: 20000 },
{ desc: "iPhone X", price: 30000 }
])
// let data = [
// { desc: "iPad", price: 20000 },
// { desc: "iPhone 8", price: 20000 },
// { desc: "iPhone X", price: 30000 }
// ];
useEffect(() => {
async function fetchData() {
let data: { desc: string, price: number }[] = [];
const querySnapshot = await getDocs(collection(db, "product"));
querySnapshot.forEach((doc) => {
data.push({ desc: doc.data().desc, price: doc.data().price })
console.log(`${doc.id} => ${doc.data()}`);
});
setProducts(() => [...data]);
}
fetchData();
}, [db]);
**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);
}**
return [products, setProducts**, addProduct**] as const;
}
/app/product/ProductList.tsx
取得回傳的addProduct
const [products, setProducts**, addProduct**] = useGetProducts();
加一個add(),利用addProduct()去新增產品
**function add() {**
**addProduct(newProduct);**
setNewProduct({ ...newProduct, visible: false })
console.log(products);
}
點選按鈕改呼叫add()
<Button variant="contained" color="primary" onClick={**add**}>新增</Button>
我們會發現寫進去的資料是字串,不是數字。要解決這問題:
const handleClick = function (e: React.ChangeEvent<HTMLInputElement>) {
if (e.target.name === "price") {
setNewProduct({ ...newProduct, [e.target.name]: **parseInt(e.target.value)** })
}
else {
setNewProduct({ ...newProduct, [e.target.name]: e.target.value })
}
}
<aside> 📢 注意firestore的規則必須允許write,否則,會有錯誤:
</aside>
FirebaseError: The caller does not have permission
請將權限暫時改為:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// This rule allows anyone with your database reference to view, edit,
// and delete all data in your Firestore database. It is useful for getting
// started, but it is configured to expire after 30 days because it
// leaves your app open to attackers. At that time, all client
// requests to your Firestore database will be denied.
//
// Make sure to write security rules for your app before that time, or else
// all client requests to your Firestore database will be denied until you Update
// your rules
match /{document=**} {
allow read, write: if request.time < timestamp.date(2023, 12, 1);
}
}
}