使用在 Flutter 中不起作用的流检查身份验证状态
Check authentication state using stream not working in Flutter
我正在使用 GoogleSignIn
。
在我的初始屏幕上,我使用 StreamBuilder
检查用户是否登录,并根据该数据尝试显示登录屏幕或主屏幕。
当我卸载并重新安装该应用程序时,它首次显示登录屏幕。然后它总是显示主屏幕,即使我从应用程序中退出也是如此。
下面是我的 Splash Screen
代码:
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
if (snapshot.hasData) {
print(snapshot.hasData);
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: HomeScreen(),
splash: kLogoImage,
duration: 800,
);
} else {
print(snapshot.hasData);
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: LoginScreen(),
splash: kLogoImage,
duration: 800,
);
}
},
);
}
}
下面是我的 Home Screen
代码:
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GoogleSignIn googleSignIn = GoogleSignIn();
User firebaseUser;
signOut() async {
await googleSignIn.signOut();
Navigator.pushReplacementNamed(context, MyRoutes.loginScreen);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Text('Hello'),
),
MaterialButton(
child: Text('Log out'),
color: Colors.red,
onPressed: () {
signOut();
})
],
),
);
}
}
我不知道为什么它不起作用我认为你的代码是正确的,但我有另一种方法可以做到这一点你可以使用流提供程序而不是流生成器
将流提供程序包装在您的 material 应用程序或 cupirtinoapp 之上:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider.value(
value: firebaseauht.inistance.onauthchange,
child: MaterialApp(
home: Wholescreen(),
),
);
}
}
然后全屏调用提供者:
class Wholescreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
var provider = Provider.of<User>(context);
if (provider!=null) {
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: HomeScreen(),
splash: kLogoImage,
duration: 800,
} else {
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: LoginScreen(),
splash: kLogoImage,
duration: 800,
);
}
}
}
难道GoogleSignIn和Firebase不一样?
尝试在 home screen
上用 FirebaseAuth.instance.signOut()
替换 googleSignIn.signOut()
。
改变这个:
signOut() async {
await googleSignIn.signOut();
Navigator.pushReplacementNamed(context, MyRoutes.loginScreen);
}
进入这个:
signOut() async {
await googleSignIn.disconnect();
Navigator.pushReplacementNamed(context, MyRoutes.loginScreen);
}
根据文档,disconnect 方法是撤销 authentication/signs 用户的方法。
我正在使用 GoogleSignIn
。
在我的初始屏幕上,我使用 StreamBuilder
检查用户是否登录,并根据该数据尝试显示登录屏幕或主屏幕。
当我卸载并重新安装该应用程序时,它首次显示登录屏幕。然后它总是显示主屏幕,即使我从应用程序中退出也是如此。
下面是我的 Splash Screen
代码:
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
return StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (BuildContext context, AsyncSnapshot<User> snapshot) {
if (snapshot.hasData) {
print(snapshot.hasData);
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: HomeScreen(),
splash: kLogoImage,
duration: 800,
);
} else {
print(snapshot.hasData);
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: LoginScreen(),
splash: kLogoImage,
duration: 800,
);
}
},
);
}
}
下面是我的 Home Screen
代码:
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GoogleSignIn googleSignIn = GoogleSignIn();
User firebaseUser;
signOut() async {
await googleSignIn.signOut();
Navigator.pushReplacementNamed(context, MyRoutes.loginScreen);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Text('Hello'),
),
MaterialButton(
child: Text('Log out'),
color: Colors.red,
onPressed: () {
signOut();
})
],
),
);
}
}
我不知道为什么它不起作用我认为你的代码是正确的,但我有另一种方法可以做到这一点你可以使用流提供程序而不是流生成器
将流提供程序包装在您的 material 应用程序或 cupirtinoapp 之上:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider.value(
value: firebaseauht.inistance.onauthchange,
child: MaterialApp(
home: Wholescreen(),
),
);
}
}
然后全屏调用提供者:
class Wholescreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
var provider = Provider.of<User>(context);
if (provider!=null) {
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: HomeScreen(),
splash: kLogoImage,
duration: 800,
} else {
return AnimatedSplashScreen(
splashIconSize: SizeConfig.blockSizeVertical * 16,
splashTransition: SplashTransition.fadeTransition,
nextScreen: LoginScreen(),
splash: kLogoImage,
duration: 800,
);
}
}
}
难道GoogleSignIn和Firebase不一样?
尝试在 home screen
上用 FirebaseAuth.instance.signOut()
替换 googleSignIn.signOut()
。
改变这个:
signOut() async {
await googleSignIn.signOut();
Navigator.pushReplacementNamed(context, MyRoutes.loginScreen);
}
进入这个:
signOut() async {
await googleSignIn.disconnect();
Navigator.pushReplacementNamed(context, MyRoutes.loginScreen);
}
根据文档,disconnect 方法是撤销 authentication/signs 用户的方法。