我一直在試圖通過我的應用程序的基礎上FirebaseAuth
值找出正確的方法來設置導航(即:瀏覽他們登錄後才用戶)如何正確設置基於認證的導航
所以我創建了一個場景,我有三個類,首先列出我的測試用例,然後討論我最後面臨的問題。
User
類是在我的應用程序的第一頁,它吸引它是小部件檢查是否有後currentUser
或不
class User extends StatefulWidget {
@override
_UserState createState() => new _UserState();
}
class _UserState extends State<User> {
FirebaseUser _user;
@override
initState() {
super.initState();
_checkUser();
}
@override
Widget build(BuildContext context) {
return _user == null? new SignInPage(): new HomePage();
}
_checkUser()async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
setState((){
this._user = user;
});
}
}
當應用程序在第一次啓動時,它加載SignInPage
自沒有用戶數據:
class SignInPage extends StatefulWidget {
@override
_SignInPageState createState() => new _SignInPageState();
}
class _SignInPageState extends State<SignInPage> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = new GoogleSignIn();
_handleSignIn() async{
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser.authentication;
final FirebaseUser user = await _auth.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
assert(user.email != null);
assert(user.displayName != null);
assert(!user.isAnonymous);
assert(await user.getToken() != null);
print (user);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sign In"),
centerTitle: true,
leading: new Container(),
backgroundColor: new Color.fromARGB(255,17,165,137)),
body: new Container(
child: new Center(
child:
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[new RaisedButton(
child: new Container(
child: new Row(children: <Widget>[
new Container(
child: new Image(
image: new NetworkImage(
"https://maxcdn.icons8.com/Share/icon/Logos//google_logo1600.png"),
),
margin: new EdgeInsets.only(right: 8.0)),
new Text("Login with Google", style: new TextStyle(color: Colors.redAccent)),
], mainAxisAlignment: MainAxisAlignment.center)),
onPressed:(){_handleSignIn().whenComplete((){Navigator.of(context).pushNamed("/Home");});}
,color: Colors.white),
],),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
)
],
)
)
)
);
}
}
這是我HomePage
類,這是隻有在通過身份驗證訪問;我的首頁包含了中央的RaisedButton
,並具有Text
孩子當前用戶的displayName
的,和onPressed()
行動調用_signOut()
方法,並返回到SignInage
final GoogleSignIn _googleSignIn = new GoogleSignIn();
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => new _HomePageState();
}
class _HomePageState extends State<HomePage> {
FirebaseUser _currentUser;
initState() {
super.initState();
_myUser();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Hello:)"),
),
body: new Center(
child: new RaisedButton(child: new Text(_currentUser.displayName),
onPressed:(){_signOut().whenComplete((){Navigator.of(context).pushNamed("/SignInPage");});})
),
);
}
_signOut() async {
await FirebaseAuth.instance.signOut();
await _googleSignIn.signOut();
return "Signed out";
}
_myUser()async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
setState((){
this._currentUser = user;
});
}
}
問題:
當應用程序第一次啓動時,它會像平常一樣加載
SignInPage
,但是當我成功登錄到我的Google帳戶時,它凍結而不導航我,因爲displayName was called on Null
,從我的理解,撲沒有足夠的時間來準備用戶數據導航發生前,我猜測是因爲在點2發生了什麼和3當重新啓動應用程序,並保留先前的身份驗證會話本,該應用程序將自動從
Home
頁開始,並正確顯示displayName。在同一次會議上,我點擊它簽署了
RaisedButton
正確導航我回到SignInPage
,我嘗試再次登錄,我們又回到了主要問題,它會嘗試之前的導航我到我Home
獲得displayName
。
這是我如何理解問題,所以我在這裏做錯了什麼,以及如何設計正確的流程?
P.S:我想這樣做的原因是因爲我想在我的HomePage
使用的currentUser
一些數據。
更新:
控制檯打印如下:
'package:test/SignInScreen.dart': Failed assertion: line 26: 'user.email != null': is not true.
這是在_handleSignIn
assert
語句。
我也嘗試創建一個預置主頁,發生同樣的問題,我不知道現在有什麼問題。
我仍然遇到同樣的問題,但讓我們說如果hasData是false,那麼如何保持主頁的加載直到它是真實的,什麼樣的佔位符將重定向到我的家當currentUser()終於準備好了。 如果您在帖子中查看更新的部分,您會發現我甚至試圖在SignInPage之後放置一個虛擬頁面,以便爲我的HomePage準備好一切,並且仍然是同樣的問題。 – aziza
,當我們檢查_currentUser爲null時,我們知道它是空的,至少對於當前運行,直到我重新啓動應用程序,這是問題的核心。 – aziza
請問你有沒有設法重現相同的問題,或者我錯過了什麼? – aziza