无法在 flutter 中退出 firebase
Cant signout of firebase in flutter
main.dart
import 'package:flutter/material.dart';
import 'package:app_name/screens/auth_screen.dart';
import 'package:app_name/screens/catalog_screen.dart';
import 'package:app_name/screens/grid_screen.dart';
import 'package:app_name/screens/outstanding.dart';
import './screens/cart_screen.dart';
import './screens/dispatch_screen.dart';
import './screens/payment_screen.dart';
import 'package:provider/provider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import './provider/selection_type.dart';
import './screens/catalog_screen.dart';
import './screens/selection.dart';
import './provider/cart_provider.dart';
import './provider/products_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
static Map<int, Color> color = {
50: Color.fromRGBO(136, 14, 79, .1),
100: Color.fromRGBO(136, 14, 79, .2),
200: Color.fromRGBO(136, 14, 79, .3),
300: Color.fromRGBO(136, 14, 79, .4),
400: Color.fromRGBO(136, 14, 79, .5),
500: Color.fromRGBO(136, 14, 79, .6),
600: Color.fromRGBO(136, 14, 79, .7),
700: Color.fromRGBO(136, 14, 79, .8),
800: Color.fromRGBO(136, 14, 79, .9),
900: Color.fromRGBO(136, 14, 79, 1),
};
MaterialColor colorCustom = MaterialColor(0xFF415dc1, color);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Products(),
),
ChangeNotifierProvider.value(
value: SelectionProvider(),
),
ChangeNotifierProvider.value(
value: Cart(),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: colorCustom, bottomAppBarColor: colorCustom),
home: StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (ctx, userSnapshot) {
if (userSnapshot.hasData) {
return Selection();
}
return AuthScreen();
},
),
routes: {
GridScreen.routeName: (ctx) => GridScreen(),
CatelogScreen.routeName: (ctx) => CatelogScreen(),
DispatchScreen.routeName: (ctx) => DispatchScreen(),
PaymentsScreen.routeName: (ctx) => PaymentsScreen(),
CartScreen.routeName: (ctx) => CartScreen(),
OutstandingScreen.routeName: (ctx) => OutstandingScreen(),
AuthScreen.routeName: (ctx) => AuthScreen(),
},
),
);
}
}
AuthScreen.dart:
import 'dart:io';
import '../widgets/auth_form.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class AuthScreen extends StatefulWidget {
static final routeName = '/auth_screen';
@override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
final _auth = FirebaseAuth.instance;
var isLoading = false;
void _submitAuthForm(
String email,
String password,
String userName,
File image,
bool isLogin,
BuildContext ctx,
) async {
AuthResult authResult;
try {
setState(() {
isLoading = true;
});
if (isLogin) {
authResult = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
} else {
authResult = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
//files upload
await Firestore.instance
.collection('users')
.document(authResult.user.uid)
.setData({
'userName': userName,
'email': email,
});
}
} on PlatformException catch (err) {
var message = 'An error occured';
if (err.message != null) {
message = err.message;
}
Scaffold.of(ctx).showSnackBar(SnackBar(
content: Text(message),
backgroundColor: Theme.of(ctx).errorColor,
));
setState(() {
isLoading = false;
});
} catch (err) {
print(err);
setState(() {
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: AuthForm(_submitAuthForm, isLoading),
);
}
}
这使得整个登录,
之后,用户登录选择页面(seletion.dart),然后移动到我使用的 gridview.dart 屏幕
FirebaseAuth.instance.signOut();
注销但网格屏幕仍然出现在屏幕上,尽管用户已注销但未显示 AuthScreen,
看起来 steamBuilder 无法收听小部件树中来自第二个 child 的请求更改,因为如果我在选择页面(直接 child)中注销,用户将注销并且屏幕会发生变化。
请帮助。
您必须 await
signOut
事件。我还建议您将其放入 Future
.
它可能看起来像这样:
Future handleSignOut() async {
try {
return await FirebaseAuth.instance.signOut();
}catch (e){
return (e)
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:app_name/screens/auth_screen.dart';
import 'package:app_name/screens/catalog_screen.dart';
import 'package:app_name/screens/grid_screen.dart';
import 'package:app_name/screens/outstanding.dart';
import './screens/cart_screen.dart';
import './screens/dispatch_screen.dart';
import './screens/payment_screen.dart';
import 'package:provider/provider.dart';
import 'package:firebase_auth/firebase_auth.dart';
import './provider/selection_type.dart';
import './screens/catalog_screen.dart';
import './screens/selection.dart';
import './provider/cart_provider.dart';
import './provider/products_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
static Map<int, Color> color = {
50: Color.fromRGBO(136, 14, 79, .1),
100: Color.fromRGBO(136, 14, 79, .2),
200: Color.fromRGBO(136, 14, 79, .3),
300: Color.fromRGBO(136, 14, 79, .4),
400: Color.fromRGBO(136, 14, 79, .5),
500: Color.fromRGBO(136, 14, 79, .6),
600: Color.fromRGBO(136, 14, 79, .7),
700: Color.fromRGBO(136, 14, 79, .8),
800: Color.fromRGBO(136, 14, 79, .9),
900: Color.fromRGBO(136, 14, 79, 1),
};
MaterialColor colorCustom = MaterialColor(0xFF415dc1, color);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Products(),
),
ChangeNotifierProvider.value(
value: SelectionProvider(),
),
ChangeNotifierProvider.value(
value: Cart(),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: colorCustom, bottomAppBarColor: colorCustom),
home: StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (ctx, userSnapshot) {
if (userSnapshot.hasData) {
return Selection();
}
return AuthScreen();
},
),
routes: {
GridScreen.routeName: (ctx) => GridScreen(),
CatelogScreen.routeName: (ctx) => CatelogScreen(),
DispatchScreen.routeName: (ctx) => DispatchScreen(),
PaymentsScreen.routeName: (ctx) => PaymentsScreen(),
CartScreen.routeName: (ctx) => CartScreen(),
OutstandingScreen.routeName: (ctx) => OutstandingScreen(),
AuthScreen.routeName: (ctx) => AuthScreen(),
},
),
);
}
}
AuthScreen.dart:
import 'dart:io';
import '../widgets/auth_form.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class AuthScreen extends StatefulWidget {
static final routeName = '/auth_screen';
@override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
final _auth = FirebaseAuth.instance;
var isLoading = false;
void _submitAuthForm(
String email,
String password,
String userName,
File image,
bool isLogin,
BuildContext ctx,
) async {
AuthResult authResult;
try {
setState(() {
isLoading = true;
});
if (isLogin) {
authResult = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
} else {
authResult = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
//files upload
await Firestore.instance
.collection('users')
.document(authResult.user.uid)
.setData({
'userName': userName,
'email': email,
});
}
} on PlatformException catch (err) {
var message = 'An error occured';
if (err.message != null) {
message = err.message;
}
Scaffold.of(ctx).showSnackBar(SnackBar(
content: Text(message),
backgroundColor: Theme.of(ctx).errorColor,
));
setState(() {
isLoading = false;
});
} catch (err) {
print(err);
setState(() {
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: AuthForm(_submitAuthForm, isLoading),
);
}
}
这使得整个登录,
之后,用户登录选择页面(seletion.dart),然后移动到我使用的 gridview.dart 屏幕
FirebaseAuth.instance.signOut();
注销但网格屏幕仍然出现在屏幕上,尽管用户已注销但未显示 AuthScreen,
看起来 steamBuilder 无法收听小部件树中来自第二个 child 的请求更改,因为如果我在选择页面(直接 child)中注销,用户将注销并且屏幕会发生变化。
请帮助。
您必须 await
signOut
事件。我还建议您将其放入 Future
.
它可能看起来像这样:
Future handleSignOut() async {
try {
return await FirebaseAuth.instance.signOut();
}catch (e){
return (e)
}
}