0

我正在開發一個使用Ionic 3和Firebase作爲身份驗證提供程序的混合應用程序。該應用程序包含2頁。登錄頁面和主頁。在登錄頁面上有一個按鈕,使用電子郵件+密碼登錄用戶,在主頁上有另一個按鈕登出當前用戶。基本上,應用程序第一次加載一切正常。但是,在登錄後,然後註銷,然後再次登錄onAuthStateChange中的函數被調用兩次,然後三次,然後是斐波那契數列之後的五次。 這是登錄頁面代碼:firebase onAuthStateChanged遵循Fibonacci的系列

firebase.auth().onAuthStateChanged(function(user) { 
     if (user) { 
     console.log('User logged-in'); 
     if (user.emailVerified) { 
      self.goToHome(); 
     } else { 
      self.showAlert(); 
      firebase.auth().signOut(); 
     } 
     } 
    }); 
    } 

,這是註銷代碼:

firebase.auth().onAuthStateChanged(function(user) { 
     if (user == null) { 
      console.log('User logged-out'); 
      navCtrl.push(WelcomePage); 
     } 
     }); 

鉻控制檯顯示此行爲:

(將在圖像結束的錯誤是我的故障,因爲我使用了錯誤的密碼)

Chrome console showing the functions getting called following the Fibonacci series

移動用戶主頁

doLogin() { 
    console.log('Trying to log in...'); 
    var email = this.account.email; 
    var password = this.account.password; 
    if (this.validateEmail(email) && password.length >= 8) { 
     loading.present(); 
     firebase.auth().signInWithEmailAndPassword(email, password) 
     .then(function(data) { 
     loading.dismiss(); 
     }); 
} 

logout() { 
    firebase.auth().signOut(); 
    } 

功能goToHome:

goToHome() { 
    this.navCtrl.push(MainPage); 
    } 

(但我99%肯定問題onAuthStateChanged)由按鈕叫個

功能解決方案在他的評論中指出Ben

1:從onAuthStateChanged移動所有navController相關的功能2:使用setRoot而不是流行()和推()

goToHome() { 
    this.navCtrl.setRoot(HomePage); 
    } 
logout() { 
    firebase.auth().signOut(); 
    this.navCtrl.setRoot(WelcomePage); 
} 

3)要解決能夠自動登錄用戶,如果他/她沒有登出我檢查 如果firebase.auth() .currentuser存在,但使用超時,因爲 火力地堡需要一些時間正常運行前:

setTimeout(function(){ 
     var user = firebase.auth().currentUser; 
     if (user != null) { 
      self.goToHome(); 
     } 
     }, 1500); 
+0

請再提一下你的'component'路由邏輯。這是做什麼'self.goToHome();'? – Hareesh

回答

0

我看到你在推動你的頁面onAuthStateChanged。這可能會導致問題。

  1. 在第一個登錄頁面創建1 onAuthStateChanged login當你點擊登錄你推1新主頁
  2. 在主頁上創建1 onAuthStateChanged logout當您單擊註銷你把1個新的登錄頁面(讓你擁有2登錄頁面點擊後加載
  3. 點擊登錄新登錄頁面後,您不會創建1個新的註銷頁面,但是由於您已有2個onAuthStateChanged login,因此會導致3個註銷頁面加載和3 onAuthStateChanged logout
  4. 當您單擊登出新的主頁,你叫3 onAuthStateChanged logout,從而創建3個新的登錄頁面+2個現有的登錄頁面= 5
  5. 等等。

爲了測試,如果是這樣的話,你就可以開始登錄頁面加載你的模塊,當你登錄你按下主頁,當你退出,你不推的登錄頁面,但popToRoot()

希望這會有所幫助,

+0

使用'popToRoot()'解決了一半的問題。現在基本上我有一個WelcomPage的實例,但我仍然得到多個HomePage的支持。所以問題出在註銷裏面。 –

+0

奇怪,但好的一半已經解決了,主頁實例化了多少次?斐波那契也像? – Ben

+0

主頁的行爲與之前一樣,意味着遵循斐波那契數列的實例化,但是比之前增加了一半 –

0

您應該firebase.auth().signInWithEmailAndPassword(email, password)後用戶發送到頁面,而不是聽衆。火力地堡的聽衆有一個奇怪的行爲...

試試這個:

doLogin() { 
    console.log('Trying to log in...'); 
    var email = this.account.email; 
    var password = this.account.password; 
    if (this.validateEmail(email) && password.length >= 8) { 
     loading.present(); 
     firebase.auth().signInWithEmailAndPassword(email, password).then(function(data) { 
      loading.dismiss(); 
      var user = firebase.auth().currentUser; 
      if (user) { 
       console.log('User logged-in'); 
       if (user.emailVerified) { 
        self.goToHome(); 
       } else { 
        self.showAlert(); 
        firebase.auth().signOut(); 
       } 
      } else { 
      // No user is signed in. 
      } 
     }, function(error) { 
     //error handling 
     }); 
    } 
} 
+0

我也考慮過這個解決方案,但這樣用戶每次關閉頁面時都必須進行身份驗證。 –

+0

一旦您初始化應用程序並進入着陸頁,請驗證用戶是否已經在那裏,如果是,則不需要詢問憑據... –

+0

Alredy嘗試這種方式,但firebase需要一些時間來初始化,所以我需要等待x時間,然後檢查用戶是否已經在那裏,這似乎並不是一個優雅的解決方案 –

0

我在登錄過類似的問題。功能/監聽器firebase.auth().onAuthStateChanged(將在每次身份驗證狀態發生變化時觸發,我期望您的onAuthStateChanged代碼中的問題與firebase.auth().signOut();會觸發新的onAuthStateChanged ...導致奇怪的初始行爲。

您已經放置firebase.auth().signOut();在您的註銷按鈕,我建議你從onAuthStateChanged登錄頁面上刪除firebase.auth().signOut();,那麼我期待斐波那契會停止(但你真的想讓它停下來?)

讓我知道這是否得到任何結果。希望它有幫助,

+0

它不能解決問題因爲signout()僅在電子郵件未通過驗證時纔會被調用,但情況並非如此 –

+0

嗯,也許是另一個問題:我看到您正在推送頁面,首先推入Login Page(編譯第一個onAuthStateChanged,然後按Login頁(它不會破壞先前的登錄頁面),然後再次將歡迎頁面(= Login Page??)發送給第二個onAuthStateChanged ...當您登錄再次調用2 onAuthStateChanged將推送2個主頁,當您註銷該頁面時,您推送1 + 2(1個來自第一個和2個新頁面)您創建2 + 3用戶登錄的歡迎頁面...導致一個斐波那契數列 – Ben

+0

我將'this.navCtrl.push(WelcomPage)'改成了'this.navCtrl.pop()',但現在該應用程序在系列啓動時崩潰,因爲第一次調用'pop()'後第二次離子找不到可以彈出的頁面。但你是對的,推動而不是彈出是錯誤的,仍然在AuthStateChanged創建問題.. –