Firebase-V8 與 V9 的超級比一比

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: '...'
}

// init firebase
firebase.initializeApp(firebaseConfig)

// init services
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: '...'
}

// init firebase
initializeApp(firebaseConfig)

// init service
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)
// client state
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])
MUI 筆記 修改 npm 安裝位置(Global)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×