好吧,我制作了這個圖書館應用程式,用戶可以在其中登錄并添加書籍。因此,當用戶登錄應用程式時,從 firestore 集合中獲取資料,很酷。當用戶登錄一次,退出然后再次登錄而不重繪 應用程式時存在問題。如果用戶執行此操作兩次,則獲取兩次,如果是三次,則獲取三次。該代碼執行多次其 fetchBooks()時,signInWithGoogle()只執行一次。這是涉及的代碼:
function signInWithGoogle(){
const provider = new firebase.auth.GoogleAuthProvider()
auth.signInWithPopup(provider)
.then(result => {
// Create the new user document in firestore
createNewUserDocument(result.user)
// fetch feed data
auth.onAuthStateChanged(user =>{
user? fetchBooks() : null
})
}).catch(err => {
console.log(err)
})
signUpForm.reset()
signUpModal.hide()
signInForm.reset()
signInModal.hide()
}
function fetchBooks() {
const docRef = db.collection('users').doc(auth.currentUser.uid).collection('books')
docRef.get().then(querySnapshot =>{
console.log(querySnapshot)
querySnapshot.forEach(doc => {
const data = doc.data()
console.log(doc.data());
addCardToHTML(data.title, data.author, data.pages, data.description, data.read)
})
})
}
uj5u.com熱心網友回復:
onAuthStateChanged 是一種訂閱,當用戶的身份驗證狀態發生變化時會觸發自身。
所以它會在您登錄、注銷等時觸發。
所以理想情況下,您希望等到用戶登錄,然后呼叫該fetchBooks()函式,但如果您繼續在訂閱者內部執行此操作,則該函式將在訂閱者發出新值時觸發。
uj5u.com熱心網友回復:
我建議從重構您的代碼開始,使其具有執行單獨操作的函式。現在,您有一個函式signInWithGoogle。該函式應該只讓用戶使用 Google 登錄并回傳一個帶有登錄結果的承諾。相反,您讓它登錄用戶,獲取書籍(它本身也在獲取書籍并修改 DOM),并呼叫方法在您的注冊元素上。
將其重構為具有其他一些頂級功能可能會幫助您更輕松地處理問題。具體來說,嘗試這樣的事情:
function handleSignIn() {
signInWithGoogle()
.then(fetchBooks)
.then(books => {
books.forEach(book => addCardToHTML(...))
})
}
這是一個好的開始,因為現在很清楚每個單獨的功能在做什么。所以現在要處理您的具體問題,我假設您面臨的問題是您看到書籍被多次添加。在那種情況下,我認為你想要發生的是:
- 當用戶登錄時,您希望加載他們的圖書并將其顯示在頁面上。
- 當他們注銷時,您希望從螢屏上卸載書籍
- 當他們重新登錄時,這些書籍會重新加載并顯示出來。
如果所有這些假設都是正確的,那么您的問題不在于您擁有的代碼,而在于注銷功能。當用戶退出時,您需要添加一個函式來從 HTML 中洗掉書籍。這樣,當他們退出后重新登錄時,handleSignIn 函式將再次啟動,并且 addCardToHTML 函式將在空白 HTML 頁面上運行,而不是在已有卡片的頁面上運行。
例子:
function handleSignOut() {
signOut()
.then(clearBookCards)
}
function clearBookCards() {
// Manipulate DOM to remove all of the card HTML nodes
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/368328.html
標籤:javascript 火力基地 谷歌云firestore Firebase 身份验证
