今天回歸實作,主要處理:
addDoc
改為setDoc
collection
改成doc
export class FbService {
registerAccount = async (userInfo) => {
let isRegisterSuccessful = false;
try {
const data = await createUserWithEmailAndPassword(auth, userInfo.value.email, userInfo.value.pwd);
console.log("successfully registered", data);
const userRef = doc(db, "users", data.user.uid); //將collection改成doc
const userDoc = {
UID: data.user.uid,
name: userInfo.value.name,
email: userInfo.value.email
};
await setDoc(userRef, userDoc); // 使用 setDoc 函數將文檔添加到集合中
isRegisterSuccessful = true;
console.log("User added to Firestore");
} catch (error) {
console.error("Register Fail: ", error.code);
}
return isRegisterSuccessful;
};
在註冊一筆新資料後,印出使用者資料確認uid以及email。
回到網頁的firestore確認,可以看到名稱為uid的使用者資料已經被加進去資料庫了。
<div>
<label for="email" class="text-white">User Email: {{ userRef.email }}</label>
</div>
<div>
<label for="displayName" class="text-white">User Name: </label>
<span v-if="!editing" class="text-white">{{ userRef.name }}</span>
</div>
//<script setup>的部分
const userRef = ref({ email: "", name: "" })
onMounted(() => {
const auth = getAuth()
const db = getFirestore()
onAuthStateChanged(auth, async (user) => {
if (user) {
userRef.value = user
console.log("User UID:", user.uid) //確認拿取的的UID正確與否
const userDocRef = doc(db, "users", user.uid)
console.log(userDocRef) //拿取到的物件
const userDoc = await getDoc(userDocRef)
console.log(userDoc.data()) //物件裡面的值們
userRef.value = {
...userRef.value, // 保留 userRef.value 對象的原有属性
...userDoc.data() // 將userDoc.data() 對象的属性合併到 userRef.value對象中
}
}
})
可以看見畫面上首先印出目前登入使用者的詳細資訊。
按下Edit Profile後,讓使用者進入編輯模式
按下完成後,可以看見無論是網站以及資料庫內資料已經被更新完畢。
//在Edit Profile加上startEditing,掌控editing監控按鈕的顯示與否
// 再用v-model雙向綁定資料
// 在完成按鈕與取消按鈕上,
// 創建completeEditing跟canceling Editing 兩個事件,
//分別掌管修改資料以及取消
<div>
<label for="displayName" class="text-white">User Name: </label>
<span v-if="!editing" class="text-white">{{ userRef.name }}</span>
<input v-if="editing" v-model="editedDisplayName" />
<button
v-if="editing"
class="text-white"
@click="completeEditing"
>
Complete
</button>
<button
v-if="editing"
class="text-white"
@click="cancelEditing"
>
Cancel
</button>
</div>
</div>
<button
class="text-white"
@click="startEditing"
>
Edit Profile
</button>
由於需要實時監聽editedDisplayName的變化,並確保在取消編輯時退回原始值,使用了watch
參數
watch(editedDisplayName, (newValue, oldValue) => {
console.log(oldValue)
if (!editing.value && newValue !== userRef.value.name) {
editedDisplayName.value = userRef.value.name
}
})
各按鈕的事件:未來是否可以模組化?
/**
* 開始編輯,故一開始為true
*/
const startEditing = () => {
editing.value = true
editedDisplayName.value = userRef.value.name
}
/**
* 完成編輯
*/
const completeEditing = () => {
editing.value = false
updateUserProfile()
}
/**
* 取消編輯
*/
const cancelEditing = () => {
editing.value = false
editedDisplayName.value = userRef.value.name
}
將更新後的資料加入資料庫:
/**
* 更新userprofile
*/
const updateUserProfile = async () => {
try {
const user = userRef.value
const db = getFirestore()
const userDocRef = doc(db, "users", user.uid)
await updateDoc(userDocRef, {
name: editedDisplayName.value
})
userRef.value = {
...userRef.value,
name: editedDisplayName.value
}
console.log("User profile updated successfully!", editedDisplayName.value)
} catch (error) {
console.error("Error updating user profile:", error)
}
}