Different Style.
重點
V8 跟 V9 最大的差別在於「模組化」,在 V8 中我們通常是直接把整個 firebase 物件拿出來使用,像是:
firebase.firestore
firebase.auth()
But,在 V9 裡面把每個東西都變成了「模組」,意思就是你要想什麼功能就拿什麼出來用,像是:
import { getFirestore } from 'firebase/firestore'
import { createUserWithEmailAndPassword } from "firebase/auth"
據說 V9 這樣的效能會比較好,因為 bundle 後的體積會比較小一點。
初始化設定
V8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import firebase from 'firebase/app' import 'firebase/firestore'
const firebaseConfig = { apiKey: '...', authDomain: '...', projectId: '...', storageBucket: '...', messagingSenderId: '...', appId: '...' }
firebase.initializeApp(firebaseConfig)
const db = firebase.firestore() const auth = firebase.auth() const storage = firebase.storage() const timestamp = firebase.firestore.Timestamp const filedValue = firebase.firestore.FieldValue
export { db, auth, timestamp, storage, filedValue }
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { initializeApp } from 'firebase/app' import { getFirestore } from 'firebase/firestore'
const firebaseConfig = { apiKey: '...', authDomain: '...', projectId: '...', storageBucket: '...', messagingSenderId: '...', appId: '...' }
initializeApp(firebaseConfig)
const db = getFirestore() const auth = getAuth()
export { db, auth }
|
讀取 collection
V8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { db } from '../firebase/config'
useEffect(() => { db.collection('books') .get() .then((snapshot) => { if (snapshot.empty) throw new Error('This collection is empty') const result = [] snapshot.forEach((doc) => { result.push({ id: doc.id, ...doc.data() }) }) setBooks(result) }) .catch((error) => { console.log('ERROR', error.message) }) }, [])
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import { db } from '../firebase/config' import { collection, getDocs } from 'firebase/firestore'
useEffect(() => { const ref = collection(db, 'books') getDocs(ref) .then((snapshot) => { if (snapshot.empty) throw new Error('This collection is empty') const result = [] snapshot.forEach((doc) => { result.push({ id: doc.id, ...doc.data() }) }) setBooks(result) }) .catch((error) => { console.log('ERROR', error.message) }) }, [])
|
Real-Time Data
V8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import { db } from '../firebase/config'
export default function Home() { const [books, setBooks] = useState(null)
useEffect(() => { const unsubscribe = db.collection('books').onSnapshot({ next: (snapshot) => { const result = [] snapshot.docs.forEach((doc) => { result.push({ ...doc.data(), id: doc.id }) }) setBooks(result) }, error: (error) => console.log(error.message) })
return () => unsubscribe() }, [])
return ( <div className='App'> {books && <BookList books={books} />} <BookForm /> </div> ) }
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import { db } from '../firebase/config' import { collection, getDocs, onSnapshot } from 'firebase/firestore'
export default function Home() { const [books, setBooks] = useState(null)
useEffect(() => { const ref = collection(db, 'books') const unsubscribe = onSnapshot(ref, { next: (snapshot) => { const result = [] snapshot.forEach((doc) => { result.push({ id: doc.id, ...doc.data() }) }) setBooks(result) }, error: (error) => console.log(error.message) }) return () => unsubscribe() }, [])
return ( <div className='App'> {books && <BookList books={books} />} <BookForm /> </div> ) }
|
新增 document
V8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { db } from '../firebase/config'
const handleSubmit = async (e) => { e.preventDefault() try { const addedDoc = await db.collection('books').add({ title: newBook }) console.log(addedDoc) setNewBook('') } catch (error) { console.log(error.message) } }
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { db } from '../firebase/config' import { addDoc, collection } from 'firebase/firestore'
const handleSubmit = async (e) => { e.preventDefault() const ref = collection(db, 'books') try { const addedDoc = await addDoc(ref, { title: newBook }) console.log(addedDoc) setNewBook('') } catch (error) { console.log(error.message) } }
|
刪除 document
V8:
1 2 3 4 5
| import { db } from '../firebase/config'
const handleClick = async (id) => { await db.collection.doc(id).delete() }
|
V9:
1 2 3 4 5 6 7 8 9
| import { db } from '../firebase/config' import { deleteDoc, doc } from 'firebase/firestore'
const handleClick = async (id) => { const ref = doc(db, 'books', id) await deleteDoc(ref) }
|
更新 document
V8:
1 2 3 4 5 6 7
| import { db } from '../firebase/config'
const handleUpdate = async (id) => { db.collection('books').doc(id).update({ price: 100 }) }
|
V9:
1 2 3 4 5 6 7 8 9 10
| import { db } from '../firebase/config' import { updateDoc } from 'firebase/firestore'
const handleUpdate = async (id) => { const ref = doc(db, 'books', id) await updateDoc(ref, { price: 100 }) }
|
註冊
V8:
1 2 3 4 5 6 7 8 9
| import { auth } from '../firebase/config'
const handleSubmit = async () => { try { const response = await auth.createUserWithEmailAndPassword(email, password) } catch (error) { console.log(error.message) } }
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { auth } from '../firebase/config' import { createUserWithEmailAndPassword } from 'firebase/auth'
const handleSubmit = async (e) => { e.preventDefault() try { const response = await createUserWithEmailAndPassword(auth, email, password) console.log('success', response) } catch (error) { console.log(error.message) } }
|
登入
V8:
1 2 3 4 5 6 7 8 9 10 11
| import { auth } from '../firebase/config'
const handleSubmit = async (e) => { e.preventDefault() try { const response = await auth.signInWithEmailAndPassword(email, password) login(response.user) } catch (error) { console.log(error.message) } }
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { auth } from '../firebase/config' import { signInWithEmailAndPassword } from 'firebase/auth'
const handleSubmit = async (e) => { e.preventDefault() try { const response = await signInWithEmailAndPassword(auth, email, password) login(response.user) } catch (error) { console.log(error.message) } }
|
登出
V8:
1 2 3 4 5 6
| import { auth } from '../firebase/config'
const logout = async () => { await auth.signOut() setUser(null) }
|
V9:
1 2 3 4 5 6 7 8 9
| import { auth } from '../firebase/config' import { signOut } from 'firebase/auth'
const logout = async () => { await signOut(auth) setUser(null) }
|
Real-Time state
V8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import { auth } from '../firebase/config'
useEffect(() => { const unsubscribe = auth.onAuthStateChanged( (user) => { console.log('USER', user) setUser(user) unsubscribe() }, (error) => { console.log(error.message) setUser(null) unsubscribe() } ) }, [])
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { auth } from '../firebase/config' import { onAuthStateChanged } from 'firebase/auth'
useEffect(() => { const unsubscribe = onAuthStateChanged( auth, (user) => { console.log('USER', user) setUser(user) unsubscribe() }, (error) => { console.log(error.message) setUser(null) unsubscribe() } ) }, [])
|
Query
V8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { db } from '../firebase/config'
useEffect(() => { let ref = db.collection('books') ref = ref.where('uid', '==', user.uid) const unsubscribe = ref.onSnapshot({ next: (snapshot) => { const result = [] snapshot.forEach((doc) => { result.push({ id: doc.id, ...doc.data() }) }) setBooks(result) }, error: (error) => console.log(error.message) }) return () => unsubscribe() }, [user.uid])
|
V9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import { collection, onSnapshot, where, query } from 'firebase/firestore' import { db } from '../firebase/config'
useEffect(() => { let ref = collection(db, 'books') ref = query(ref, where('uid', '==', user.uid)) const unsubscribe = onSnapshot(ref, { next: (snapshot) => { const result = [] snapshot.forEach((doc) => { result.push({ id: doc.id, ...doc.data() }) }) setBooks(result) }, error: (error) => console.log(error.message) }) return () => unsubscribe() }, [user.uid])
|