我正在尝试为链接到Firebase的应用程序创建一个登录页面。我已经设置了所需的字段,当我提交表单时,出现以下错误:
I/flutter (17068): 'package:firebase_auth/src/firebase_auth.dart': Failed assertion: line 61 pos 12: 'email != null': is not true.
我已确保在运行模拟器时填写了每个字段,但仍无法弄清为什么此字段不起作用。这是代码:
import 'package:easy_tiger/constants/appbar.dart';
import 'package:easy_tiger/screens/account.dart';
import 'package:easy_tiger/style.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:easy_tiger/services/auth_service.dart';
enum AuthFormType { signIn, signUp }
class SignUpPage extends StatefulWidget {
final AuthFormType authFormType;
SignUpPage({Key key, this.authFormType}) : super(key: key);
@override
_SignUpPageState createState() => _SignUpPageState(authFormType: this.authFormType);
}
class _SignUpPageState extends State<SignUpPage> {
AuthFormType authFormType;
_SignUpPageState({this.authFormType});
final formKey = GlobalKey<FormState>();
String _firstName,
_lastName,
_email,
_confirmEmail,
_password,
_confirmPassword,
_dateOfBirth;
void switchFormState(String state) {
formKey.currentState.reset();
if(state == 'signUp') {
setState(() {
authFormType = AuthFormType.signUp;
});
} else {
setState(() {
authFormType = AuthFormType.signIn;
});
}
}
void submit() async {
final form = formKey.currentState;
form.save();
try {
final auth = Provider.of(context).auth;
if(authFormType == AuthFormType.signIn) {
String uid = await auth.signInWithEmailAndPassword(_email, _password);
print("Signed In with ID $uid");
Navigator.of(context).pushReplacementNamed('/home');
} else {
String uid = await auth.createUserWithEmailAndPassword(_firstName,
_lastName, _email,_confirmEmail, _password, _confirmPassword,
_dateOfBirth);
print("Signed up with New ID $uid");
Navigator.of(context).pushReplacementNamed('/home');
}
} catch (e) {
print (e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(80),
child: MainAppBar(
text: buildAppBarText(),
)),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
child: Container(
child: Column(
children: <Widget>[
Align(
child: Text(buildTitleText(), style: AppBarTextStyle),
),
Container(
padding: EdgeInsets.only(top: 10),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: formKey,
child: Column(
children: buildInputs() + buildSwitchText(),
)),
),
],
),
),
),
),
));
}
buildHeaderText() {
String _headerText;
if (authFormType == AuthFormType.signUp) {
_headerText = "Don't have an account?";
} else {
_headerText = "Already have an account?";
} return _headerText;
}
List<Widget> buildInputs() {
List<Widget> textFields = [];
if (authFormType == AuthFormType.signIn) {
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Email'),
onSaved: (value) => _email
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Password'),
obscureText: true,
onSaved: (value) => _password,
),);
}
else {
//if we're in the sign up state, add name
// add email & password
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('First Name'),
onSaved: (value) => _firstName,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Last Name'),
onSaved: (value) => _lastName,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Email Address'),
onSaved: (value) => _email,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Confirm Email Address'),
onSaved: (value) => _confirmEmail,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Password'),
obscureText: true,
onSaved: (value) => _password,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Confirm Password'),
onSaved: (value) => _confirmPassword,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Date of Birth'),
onSaved: (value) => _dateOfBirth,
));
textFields.add(SizedBox(
height: 15,
));
}
return textFields;
}
List<Widget> buildSwitchText() {
String _switchButtonTextPart1, _switchButtonTextPart2,_newFormState;
if(authFormType == AuthFormType.signIn) {
_switchButtonTextPart1 = "Haven't got an account? ";
_switchButtonTextPart2 = 'Sign Up';
_newFormState = 'signUp';
} else {
_switchButtonTextPart1 = 'Already have an account? ';
_switchButtonTextPart2 = 'Sign In';
_newFormState = 'signIn';
} return [
SizedBox(height: 5.0),
Container(
width: MediaQuery.of(context).size.height * 0.7,
child: RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0),),
color: kPrimaryColor,
textColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(_switchButtonTextPart2,
style: TextStyle(fontFamily: FontNameDefault,
fontSize: 15.0),),
),
onPressed: submit),
),
SizedBox(height: 5.0,),
RichText(
text: TextSpan(
style: TextStyle(
fontFamily: FontNameDefault,
color: Colors.black,
fontSize: 12.0,
),
children: <TextSpan>[
TextSpan(
text: _switchButtonTextPart1
),
TextSpan(
text: _switchButtonTextPart2,
style: TextStyle(
decoration: TextDecoration.underline,
color: Colors.black,
fontSize: 12.0),
recognizer: TapGestureRecognizer()
..onTap = () {
switchFormState(_newFormState);
})
]),
),
];
}
String buildAppBarText() {
String _switchAppBarHeader;
if(authFormType == AuthFormType.signIn) {
_switchAppBarHeader = "Already have an account?";
} else {
_switchAppBarHeader = "Don't have an account?";
} return
_switchAppBarHeader;
}
String buildTitleText() {
String _switchTextHeader;
if(authFormType == AuthFormType.signIn) {
_switchTextHeader = "Sign In";
} else {
_switchTextHeader = "Sign Up";
} return
_switchTextHeader;
}
}
class AccountController extends StatelessWidget {
@override
Widget build(BuildContext context) {
final AuthService auth = Provider.of(context).auth;
return StreamBuilder(
stream: auth.onAuthStateChanged,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
final bool signedIn = snapshot.hasData;
return signedIn ? SignInPage() : SignUpPage();
}
return CircularProgressIndicator();
});
}
}
InputDecoration buildSignUpInputDecoration(String hint) {
return InputDecoration(
isDense: true,
fillColor: Colors.white,
hintText: hint,
filled: true,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 0.0),
),
contentPadding: const EdgeInsets.only(left: 14.0, bottom: 10.0, top: 10.0),
);
}
class Provider extends InheritedWidget {
final AuthService auth;
Provider({Key key, Widget child, this.auth}) : super(key: key, child: child);
@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return true;
}
static Provider of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<Provider>();
}
答案 0 :(得分:0)
在提交表单之前,请尝试formkey.vadlidate,以确认同时获取了电子邮件和密码,并且还需要确保已将其标记为必填项。
答案 1 :(得分:0)
设法通过更改来解决此问题:
if (authFormType == AuthFormType.signIn) {
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Email'),
validator: EmailValidator.validate,
onSaved: (value) => _email
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Password'),
obscureText: true,
validator: PasswordValidator.validate,
onSaved: (value) => _password,
),);
}
到...
if (authFormType == AuthFormType.signIn) {
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Email'),
validator: EmailValidator.validate,
onSaved: (value) => _email = value
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Password'),
obscureText: true,
validator: PasswordValidator.validate,
onSaved: (value) => _password = value,
),);
}