flutter - 提供者侦听器确实更新了包装器小部件
问题描述
我一直在关注Firebase Auth上的 netninja 教程,但遇到了问题。我的签名运行良好,我的包装器中的侦听器在登录后直接将用户发送到我的主页。但是,尽管注册成功,我的注册页面并没有继续发送用户。对此的任何和所有帮助将不胜感激。
这是我的注册页面:
class SignUpWidget extends StatefulWidget {
@override
SignUpState createState() => SignUpState();
}
class SignUpState extends State<SignUpWidget> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
String error = '';
bool loading = false;
// text field state
String displayName = '';
String email = '';
String password = '';
@override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: const Color.fromARGB(255, 69, 90, 100),
body: SafeArea(
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.only(top: 40, left: 20, right: 20),
child: Column(
children: <Widget>[
Card(
elevation: 2.0,
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
padding:
const EdgeInsets.only(top: 30, bottom: 30),
child: const Icon(
FontAwesomeIcons.bookOpen,
size: 60,
color: Color.fromARGB(255, 69, 90, 100),
),
),
Padding(
padding: const EdgeInsets.only(
top: 1.0,
bottom: 1.0,
left: 25.0,
right: 25.0,
),
child: TextFormField(
validator: (val) =>
val!.isEmpty ? 'Enter your name' : null,
onChanged: (val) {
setState(() => displayName = val);
},
style: const TextStyle(
fontFamily: "Montserrat",
fontSize: 16.0,
color: Colors.black,
),
decoration: const InputDecoration(
border: InputBorder.none,
icon: Icon(
FontAwesomeIcons.solidUser,
color: Color.fromARGB(255, 69, 90, 100),
size: 22.0,
),
hintText: "Enter name",
hintStyle: TextStyle(
fontFamily: "Montserrat",
fontSize: 18.0,
),
),
),
),
Container(
width: 250.0,
height: 1.0,
color: Colors.grey,
),
Padding(
padding: const EdgeInsets.only(
top: 5.0,
bottom: 5.0,
left: 25.0,
right: 25.0,
),
child: TextFormField(
validator: (val) =>
val!.isEmpty ? 'Enter your email' : null,
onChanged: (val) {
setState(() => email = val);
},
style: const TextStyle(
fontFamily: "Montserrat",
fontSize: 16.0,
color: Colors.black,
),
decoration: const InputDecoration(
border: InputBorder.none,
icon: Icon(
FontAwesomeIcons.solidEnvelope,
color: Color.fromARGB(255, 69, 90, 100),
size: 22.0,
),
hintText: "Enter email",
hintStyle: TextStyle(
fontFamily: "Montserrat",
fontSize: 18.0,
),
),
),
),
Container(
width: 250.0,
height: 1.0,
color: Colors.grey,
),
Padding(
padding: const EdgeInsets.only(
top: 5.0,
bottom: 5.0,
left: 25.0,
right: 25.0,
),
child: TextFormField(
validator: (val) => val!.length < 6
? 'Enter a password 6+ chars long'
: null,
obscureText: true,
focusNode: focusPassword,
controller: passwordController,
onChanged: (val) {
setState(() => password = val);
},
style: const TextStyle(
fontFamily: "Montserrat",
fontSize: 16.0,
color: Colors.black,
),
decoration: const InputDecoration(
border: InputBorder.none,
icon: Icon(
FontAwesomeIcons.lock,
color: Color.fromARGB(255, 69, 90, 100),
size: 22.0,
),
hintText: "Enter password",
hintStyle: TextStyle(
fontFamily: "Montserrat",
fontSize: 18.0,
),
),
),
),
Container(
width: 250.0,
height: 1.0,
color: Colors.grey,
),
Container(
margin: const EdgeInsets.only(top: 40.0),
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(5.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: AppColours.colorStart,
offset: Offset(1.0, 6.0),
blurRadius: 20.0,
),
BoxShadow(
color: AppColours.colorEnd,
offset: Offset(1.0, 6.0),
blurRadius: 20.0,
),
],
gradient: LinearGradient(
colors: [
AppColours.colorEnd,
AppColours.colorStart
],
begin: FractionalOffset(0.2, 0.2),
end: FractionalOffset(1.0, 1.0),
stops: [0.1, 1.0],
tileMode: TileMode.clamp,
),
),
child: MaterialButton(
highlightColor: Colors.transparent,
splashColor: AppColours.colorEnd,
child: const Padding(
padding: EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 42.0,
),
child: Text(
"Register",
style: TextStyle(
fontFamily: "Montserrat-bold",
color: Colors.white,
fontSize: 22.0,
),
),
),
onPressed: () async {
if (_formKey.currentState!.validate()) {
setState(() => loading = true);
dynamic result = await _auth
.registerWithEmailandPassword(
displayName, email, password);
if (result == null) {
setState(() {
error = 'please supply a valid email';
loading = false;
});
}
}
},
),
),
SizedBox(
height: 20,
),
Text(
error,
style: TextStyle(
color: Colors.red,
fontSize: 14,
),
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black12,
Colors.black,
],
// ignore: use_named_constants
begin: FractionalOffset(0.0, 0.0),
// ignore: use_named_constants
end: FractionalOffset(1.0, 1.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
),
),
width: 100.0,
height: 1.0,
),
const Padding(
padding: EdgeInsets.only(
left: 15.0, right: 15.0),
child: Text(
"Or register with",
style: TextStyle(
color: Colors.black,
decoration: TextDecoration.none,
fontSize: 16.0,
fontFamily: "Montserrat",
),
),
),
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black,
Colors.black12,
],
begin: FractionalOffset(0.0, 0.0),
end: FractionalOffset(1.0, 1.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp,
),
),
width: 100.0,
height: 1.0,
),
],
),
),
Padding(
padding: const EdgeInsets.only(
top: 20,
bottom: 20,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
GestureDetector(
onTap: () => {},
child: Container(
child: const Icon(
FontAwesomeIcons.facebook,
color: Color(0xFF0084ff),
size: 60,
),
),
),
GestureDetector(
onTap: () => {},
child: Container(
child: const Icon(
FontAwesomeIcons.instagram,
color: Color.fromARGB(255, 240, 58, 83),
size: 60,
),
),
),
GestureDetector(
onTap: () => {},
child: Container(
child: const Icon(
FontAwesomeIcons.twitter,
color: Color(0xFF0084ff),
size: 60,
),
),
),
GestureDetector(
onTap: () => {},
child: Container(
padding: const EdgeInsets.only(top: 5),
child: const Image(
height: 50,
width: 50,
image: AssetImage(
'images/google_logo.png'),
),
//FontAwesomeIcons.google,
//color: const Color(0xFF0084ff),
//size: 60,
),
),
],
),
),
],
),
),
),
],
),
),
),
);
}
}
这是我的包装:
class Wrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final user = Provider.of<User?>(context);
//return either homepage or Login widget
if (user == null) {
return LoginWidget();
} else {
return HomePage();
}
}
}
这是我的主要内容:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(App());
}
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initialization,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const SomethingWentWrong();
}
if (snapshot.connectionState == ConnectionState.done) {
return const MyApp();
}
return const CircularProgressIndicator();
},
);
}
}
class SomethingWentWrong extends StatelessWidget {
const SomethingWentWrong({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: Row(
children: const <Widget>[
Text('something went wrong!'),
],
),
);
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return StreamProvider<User?>.value(
value: AuthService().user,
initialData: null,
child: MaterialApp(
title: 'The Book Club',
debugShowCheckedModeBanner: false,
theme: ThemeData(
canvasColor: const Color.fromARGB(255, 207, 216, 220),
fontFamily: 'Montserrat-SemiBold',
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Wrapper(),
),
);
}
}
最后这是我的身份验证:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
//auth change user stream
Stream<User?> get user {
return _auth.authStateChanges();
}
//sign in with email and password
Future logInWithEmailandPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
User? user = result.user;
return user;
} catch (e) {
print(e.toString());
return null;
}
}
//register with email and password
Future registerWithEmailandPassword(
String name, String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
User? user = result.user;
return user;
} catch (e) {
print(e.toString());
return null;
}
}
//sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch (e) {
print(
e.toString(),
);
return null;
}
}
}
让我知道是否需要更多文件/详细信息才能回答我的问题,我不明白为什么它没有正确加载主页。
解决方案
我通过正确使用我的身份验证小部件解决了这个问题,如下所示:
class Authenticate extends StatefulWidget {
@override
_AuthenticateState createState() => _AuthenticateState();
}
class _AuthenticateState extends State<Authenticate> {
bool showLogIn = true;
void toggleView() {
setState(() => showLogIn = !showLogIn);
}
@override
Widget build(BuildContext context) {
if (showLogIn) {
return LoginWidget(toggleView: toggleView);
} else {
return SignUpWidget(toggleView: toggleView);
}
}
}
推荐阅读
- monaco-editor - Monaco Editor:通过编辑器配置库
- java - 作为对象的 HashMap 值具有被错误值覆盖的属性
- laravel - 解析错误:语法错误、意外的 '__construct' (T_STRING)、期望函数 (T_FUNCTION) 或 const (T_CONST)
- excel - 在 Excel VBA 中,如何将工作表事件从加载项运行到活动工作簿
- android - 在不同平台上从 android-ndk 构建的库是否不同
- css - 为什么在使用嵌套组件时没有在 p 标签上应用 css?
- python - 在 Python 中打开窗口并在其上绘制填充矩形的最简单方法
- angular - ExpressionChangedAfterItHasBeenCheckedError 错误,因为 Angular 6 中的加载程序拦截器
- angular - 在扩展模式下如何更改垫子扩展面板标题的内容
- java - 任何人都可以帮助转换为 lambda 表达式吗?