Firebase在coding實作的概念,與其他module一樣,必須先安裝好模組。
第一步,想來看到這裡都已經得心應手,要跑command line npm install firebase
,這時候可能遇到npm版本問題,導致報錯, ̶我̶一̶律̶建̶議̶加̶上̶f̶o̶r̶c̶e̶。
接著,打開我們在第三天建立過的firebase.js,從firebase裡面存取你的App下來,以便後續使用collection。
// firebase.js
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
apiKey: {your key},
authDomain: {your auth},
projectId: {your Id},
storageBucket: {yours},
messagingSenderId: {your Id},
appId: {yours}
};
const firebaseApp = initializeApp(firebaseConfig)
export default firebaseApp;
回到firebase的主頁,我們可以開始建立一個實際的雲端資料庫了。
從你的專案頁點入,會看到Cloud Firestore的選項,點選建立。之後在設定頁選擇Start in test mode。
完成初步設定,就可以start collection了!
為你的collection取一個ID,這一步很重要,要記得自己取的ID,因為在project中要存取你所往上送的資料,需要透過ID來找到這個collection。
繼續完成初始設定,這邊的Document ID很貼心地提供了一個隨機的選項。按下確認後,就完成Cloud Firestore的建立了。
這次引入firebase,就是在做資料的存取,我們第一時間可以反應到,它會更改到的是與todos有關的部分。
首先,要瞭解到資料庫內部存取資料,以及原先使用的const差異。我們在螢幕上看到任何資料的變化,都是const的變化,因為在React 中,狀態可以分為局部狀態和全域狀態。局部狀態是指只在單一component內部使用的狀態(即使App.js,也視為單一的component),通常使用useState來管理。全域狀態是在多個components之間共享的狀態,通常需要使用Redux或React 的 Context API來實作。
在執行全域性變化時,可以使用useEffect來監控操作。
useEffect
是 React 提供的一個鉤子函數,用於處理交互操作,例如資料獲取、訂閱、手動操作 DOM 等。它在function的設計中模擬了component的生命週期方法 componentDidMount、componentDidUpdate 和 componentWillUnmount。
所以在我們這次的實作中,主要要處理的就是:
順著這個思路,就可以完成今天的實作了。
// App.js
import { useState, useEffect } from 'react'
import { Button, FormControl, Input, InputLabel } from '@material-ui/core';
import Todo from './component/Todo'
import { getFirestore, collection, addDoc, getDocs } from "firebase/firestore";
import firebaseApp from "./firebase";
import './App.css';
function App() {
const [todos, setTodos] = useState([])
const db = getFirestore(firebaseApp);
const todosCollection = collection(db, 'todos');
const [input, setInput] = useState('');
useEffect(() => {
const fetchTodos = async () => {
const querySnapshot = await getDocs(todosCollection);
const todosData = querySnapshot.docs.map((doc) => doc.data().todo);
setTodos(todosData);
};
fetchTodos();
}, []);
const addTodo = async (input) => {
console.log("enter")
try {
// const todosCollection = collection(db, "todos");
await addDoc(todosCollection, {
todo: input,
});
console.log("Todo added successfully!");
setTodos([...todos, input])
setInput('')
} catch (error) {
console.error("Error adding todo: ", error);
}
}
return (
<div className="App">
<h1>My TODO List</h1>
<form onSubmit={(e) => { e.preventDefault(); addTodo(input); }}>
<FormControl>
<InputLabel>Write a TODO</InputLabel>
<Input value={input} onChange={e => setInput(e.target.value)} />
</FormControl>
<Button type="submit" onClick={addTodo} variant='contained' color="primary" disabled={!input}>Add TODO</Button>
</form>
<ul>
{todos.map(it => <Todo todo={it} />)}
</ul>
</div>
);
}
export default App;
最後,你可以得到一個像這樣的網頁。