如何解决Flutter / Firebase-通过登录功能在主屏幕上开始
我是扑朔迷离的新手,我正在尝试创建一个在主屏幕上打开的应用,底部带有导航栏,允许用户单击帐户图标以使他们进行注册/登录页面(如果当前尚未登录)或使用Firebase作为后端的帐户页面。
到目前为止,我已经成功创建了我的主屏幕和导航功能来注册/登录页面,如果用户已经注册,就可以从那里登录。我现在坚持将帐户页面与现有导航栏集成的最佳方法。
这是我的main.dart文件:
import 'package:easy_tiger/screens/home.dart';
import 'package:easy_tiger/screens/home_screen/homepage.dart';
import 'package:easy_tiger/screens/onboarding.dart';
import 'package:easy_tiger/screens/profileview.dart';
import 'package:easy_tiger/screens/signup.dart';
import 'package:easy_tiger/services/auth_service.dart';
import 'package:easy_tiger/style.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return Provider(
auth: AuthService(),child: MaterialApp(
title: 'Easy Tiger',theme: ThemeData(
appBarTheme: AppBarTheme(
textTheme: TextTheme(headline6: AppBarTextStyle),color: kPrimaryColor,elevation: 0.0,)
),home: Home(),routes: <String,WidgetBuilder> {
'/home': (BuildContext context) => ProfileView(),'/homepage': (BuildContext context) => MyApp()
},),);
}
}
控制导航的我的Home.dart文件:
import 'package:easy_tiger/screens/account.dart';
import 'package:easy_tiger/screens/home_screen/homepage.dart';
import 'package:easy_tiger/services/auth_service.dart';
import 'package:flutter/material.dart';
import 'signup.dart';
import 'inboxpage.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
PageController _pageController = PageController();
List<Widget> _screens = [HomePage(),InboxPage(),SignUpPage(authFormType: AuthFormType.signIn)];
int _selectedIndex = 0;
void _onPageChanged(int index) {
setState(() {
_selectedIndex = index;
});
}
void _onItemTapped(int selectedIndex) {
_pageController.jumpToPage(selectedIndex);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,children: _screens,onPageChanged: _onPageChanged,physics: NeverScrollableScrollPhysics(),bottomNavigationBar: BottomNavigationBar(onTap: _onItemTapped,items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,color: _selectedIndex == 0 ? Colors.blueAccent : Colors.grey,title: Text(
'Home',style: TextStyle(
color: _selectedIndex == 0 ? Colors.blueAccent : Colors.grey,BottomNavigationBarItem(
icon: Icon(
Icons.email,color: _selectedIndex == 1 ? Colors.blueAccent : Colors.grey,title: Text(
'Inbox',style: TextStyle(
color: _selectedIndex == 1 ? Colors.blueAccent : Colors.grey,BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,color: _selectedIndex == 2 ? Colors.blueAccent : Colors.grey,title: Text(
'Account',style: TextStyle(
color: _selectedIndex == 2 ? Colors.blueAccent : Colors.grey,]),);
}
}
我的注册/登录页面:
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';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.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;
bool validate() {
final form = formKey.currentState;
form.save();
if (form.validate()) {
form.save();
print('true');
return true;
} else {
print('false');
return false;
}
}
void switchFormState(String state) {
formKey.currentState.reset();
//formKey.currentState.validate();
if (state == 'signUp') {
setState(() {
authFormType = AuthFormType.signUp;
});
} else {
setState(() {
authFormType = AuthFormType.signIn;
});
}
}
void submit() async {
final CollectionReference userCollection =
Firestore.instance.collection('UserData');
if (validate()) {
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(
_email,);
userCollection.document(uid).setData({
'First Name': _firstName,'Last Name': _lastName,'Date of Birth': _dateOfBirth
});
print("Signed up with New ID $uid");
Navigator.of(context).pushReplacementNamed('/home');
}
} catch (e) {
print(e);
}
}
}
DateTime selectedDate = DateTime.now();
TextEditingController _date = new TextEditingController();
Future<Null> _selectDate(BuildContext context) async {
DateFormat formatter =
DateFormat('dd/MM/yyyy'); //specifies day/month/year format
final DateTime picked = await showDatePicker(
context: context,initialDate: selectedDate,firstDate: DateTime(1901,1),builder: (BuildContext context,Widget child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,onPrimary: Colors.black,buttonTheme: ButtonThemeData(
colorScheme: Theme.of(context)
.colorScheme
.copyWith(primary: Colors.black),child: child,);
},lastDate: DateTime(2100));
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
_date.value = TextEditingValue(
text: formatter.format(
picked)); //Use formatter to format selected date and assign to text field
});
}
@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 = [];
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
if (authFormType == AuthFormType.signIn) {
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,decoration: buildSignUpInputDecoration('Email'),validator: SignInEmailValidator.validate,onSaved: (value) => _email = value.trim()));
textFields.add(SizedBox(
height: 15,));
textFields.add(
TextFormField(
style: TextStyle(
fontSize: 12.0,decoration: buildSignUpInputDecoration('Password'),obscureText: true,validator: SignInPasswordValidator.validate,onSaved: (value) => _password = value.trim(),);
} else {
textFields.clear();
//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'),validator: NameValidator.validate,onSaved: (value) => _firstName = value,));
textFields.add(SizedBox(
height: 15,));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,decoration: buildSignUpInputDecoration('Last Name'),onSaved: (value) => _lastName = value,decoration: buildSignUpInputDecoration('Email Address'),onSaved: (value) => _email = value.trim(),decoration: buildSignUpInputDecoration('Confirm Email Address'),onSaved: (value) => _confirmEmail = value,validator: (confirmation) {
return confirmation == _email
? null
: "Confirm Email Address should match email address";
},onSaved: (value) => _password = value,));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,decoration: buildSignUpInputDecoration('Confirm Password'),onSaved: (value) => _confirmPassword = value,validator: (confirmation) {
return confirmation == _password
? null
: "Confirm Password should match password";
}));
textFields.add(SizedBox(
height: 15,));
textFields.add(GestureDetector(
onTap: () => _selectDate(context),child: AbsorbPointer(
child: TextFormField(
style: TextStyle(fontSize: 12.0),controller: _date,keyboardType: TextInputType.datetime,decoration: InputDecoration(
isDense: true,fillColor: Colors.white,hintText: 'Date of Birth',filled: true,enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 0.0),contentPadding:
const EdgeInsets.only(left: 14.0,bottom: 10.0,top: 10.0),onSaved: (value) => _dateOfBirth = value,));
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),textColor: Colors.black,child: Padding(
padding: const EdgeInsets.all(8.0),child: Text(
buildTitleText(),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,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,hintText: hint,enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 0.0),contentPadding: const EdgeInsets.only(left: 14.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>();
}
最后是我的account.dart文件:
import 'package:easy_tiger/constants/appbar.dart';
import 'package:easy_tiger/style.dart';
import 'package:flutter/material.dart';
import 'package:easy_tiger/services/auth_service.dart';
class SignInPage extends StatefulWidget {
@override
_SignInPageState createState() => _SignInPageState();
}
class _SignInPageState extends State<SignInPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(80),child: MainAppBar(
text: 'Have an account?',body:
Padding(
padding: const EdgeInsets.all(12.0),child: Center(
child: Container(
child: Column(
children: <Widget>[
Align(
child: Text('Sign In',Container(padding: EdgeInsets.only(top: 50),Container(
height: 30,width: MediaQuery.of(context).size.width / 1.5,child: TextField(
decoration: InputDecoration(
hintText: 'Email'
),);
}
}
解决方法
在验证用户登录时设计一个简单的加载屏幕。从FirebaseAuth撤消验证后,导航至所需页面。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。