此筆記是基於 zerotomastery.io 推出 React 課程 Complete React Developer in 2022 所撰寫。
yarn add firebase
腳色:
背後流程:
至 Firebase 新增一個網頁 App:
點選安卓圖案右邊的按鈕。
輸入一個自訂 App 名稱並且註冊:
src/utils/firebase/firebase.utils.js
貼上複製的 SDK'firebase/auth'
setCustomParameters()
,此方法接受一個 configuration 物件作為參數,去定義這個 googleAuthProvider 要有什麼行為。這邊 configuration 物件填入 {prompt: "select_account"}
,意思是當每次有人接觸到我們的 provider,我們強制他一定要選擇一個帳號(若沒有加這個選項,使用者是在登入 Google 帳號狀態下會直接默認登入該帳號):getAuth()
、signInWithPopup()
,後者參數接收 getAuth()
的結果跟 provider
,最後 export 出去:完整程式碼:
回 Firebase 網站,點選昨方欄 Authentication,選擇 Google 接著照下圖指示:
在 sign-in.component.jsx
import utils 中的 signInWithGooglePopup
,signInWithGooglePopup()
的結果會是一個 Promise 物件。
本小節完成後,進度如下,可以看到 await signInWithGooglePopup()
的結果:
user 的資訊,如 accessToken 跟 uid 等等……
注意(重要)
signInWithGooglePopup()
在做的事情是將透過 Google 登入的 user 通過 Firebase 的 Authentication 而已,並未寫入 Firestore 裡面:
Collection > Document > Data
本小節情境:
承 93. 小節,使用者透過 Google 登入後,我們要把使用者的資料存進 Firestore 裡面!
進入 Firebase 左方選擇 Firestore Database,選擇以正式版模式啟動
Cloud Firestore 位置任選
進入規則,將 allow read, write: if false
改為 allow read, write: if true
,這是為了讓我們可以對這個資料庫的 document 進行修改。
src/utils/firebase/firebase.utils.js
import 'firebase/firestore'
相關 APIdoc()
建立一個 document 實例,有兩種語法:
語法1:const userDocRef = doc(db, 'users', userAuth.uid);
語法2:const docRef = doc(collectionRef, docTitle);
補充:此時我們才剛建立 firestore,資料庫中我們沒有 userDocRef
的參照,根本也沒有 users collection,但是在呼叫 doc()
之後,firestore 還是會建立一個物件指向一個獨立的位址,讓我們把資料 set 進去。(這個物件的 ID 就是我們傳入 doc()
裡的 userAuth.uid
)
getDoc()
用來把一個 document 實例的資料取出來,參數接收一個 document 實例,會回傳 Promise 物件。
語法:const userSnapshot = await getDoc(userDocRef);
getDoc()
的結果取出來後(用 await
或是 .then()
)可直接呼叫 exists()
去判定在此 DB 中的該 collection 裡面到底存不存在這個值,這會回傳一個布林值。setDoc()
用來設定一個 document 實例的資料,第一個參數接收一個 document 實例,第二個是一個要寫進資料庫的物件,會回傳 Promise 物件。
語法:await setDoc(userDocRef, {obj});
本三節重點:
新增信箱/密碼的登入方式,藉由呼叫 createUserWithEmailAndPassword()
將透過使用信箱/密碼的 user ****通過 Firebase 的 Authentication。
createUserWithEmailAndPassword()
跟 signInWithGooglePopup()
都是將 user 通過 Firebase 的 Authentication,並且會回傳 user 的一些資訊,如 uid、accessToken 等等。回到 Firebase 左方欄 Authentication,Sign-in method 新增電子郵件/密碼,如圖:
src/components/sign-up-form/sign-up-form.component.jsx
firebase.utils.js
createUserDocumentFromAuth
(在 Firestore 建立一個 user document)新增接收 additionalInformation 參數是因為採用信箱/登入(呼叫 createUserWithEmailAndPassword(auth, email, password)
)回傳的 user 資訊的 displayName 是 null,Firebase 應另有提供方法寫入 displayName 的值,但本課程講師決定當 user 以**信箱/登入,**displayName 就採用客戶端提供之 displayName input 值。additionalInformation 就是在 SignIn 時掛上 onChange 的 displayName 欄位的值。sign-up-form.component.jsx
import { createAuthUserWithEmailAndPassword } from '../../utils/firebase/firebase.utils';
event.preventDefault()
。createAuthUserWithEmailAndPassword()
傳入 email, password 參數後呼叫後會通過 Firebase 的 Authentication 並回傳一些 user 資訊,如 accessToken、uid 等等但透過信箱/密碼方式登入不會有 displayName。createUserDocumentFromAuth()
傳入呼叫 createAuthUserWithEmailAndPassword()
回傳的 user 資訊跟客戶端提供的 displayName ⇒ 在 Firestore 存入該使用者資料src/components
下新增 form-input 資料夾,底下再新增
form-input.component.jsx
…otherProps
運用到剩餘屬性!form-input.styles.scss
本小節重點:
本專案中有三種相似 button,將 <button> 元件化並依據 class 名稱去顯示不同樣式。
src/components/button
新增 button.component.jsx
本兩小節重點:
sign-in.component.jsx
signInWithEmailAndPassword
進行登入firebase.utils.js
import {signInWithEmailAndPassword} from 'firebase/auth';
sign-in-form.component.jsx
import signInAuthUserWithEmailAndPassword
,onSubmit 事件如下: