flutter - 颤振:如何显示用户特定页面?
问题描述
尝试实现特定于用户的登录:登录后,如果用户是 A 类用户,则应显示不同的主页,如果用户是 B 类用户,则应显示单独的主页。
以下是登录小部件的代码:
class LogInWidget extends StatefulWidget {
@override
_LogInWidgetState createState() => _LogInWidgetState();
}
class _LogInWidgetState extends State<LogInWidget> {
var _formKey = GlobalKey<FormState>();
bool hide = true;
bool forgotPassword = false;
bool isLoginPressed = false;
final FirebaseAuth _auth = FirebaseAuth.instance;
final AuthMethods _authMethods = AuthMethods();
TextEditingController email = TextEditingController();
TextEditingController password = TextEditingController();
@override
Widget build(BuildContext context) {
return isLoginPressed
? Center(
child: CircularProgressIndicator(),
)
: Scaffold(
backgroundColor: UniversalVariables.blackColor,
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: ListView(
children: <Widget>[
SizedBox(
height: 80,
),
!forgotPassword
? Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Sign In',
style: TextStyle(
color: Colors.white,
fontSize: 60,
fontWeight: FontWeight.w700),
textAlign: TextAlign.center,
),
SizedBox(
height: 48.0,
),
Material(
borderRadius: BorderRadius.circular(10.0),
elevation: 0.0,
color: Colors.white.withOpacity(0.2),
child: TextFormField(
cursorColor: Colors.white,
controller: email,
textAlign: TextAlign.center,
keyboardType: TextInputType.emailAddress,
// ignore: missing_return
validator: (String value) {
if (value.isEmpty) {
return "please enter a value";
}
},
style: TextStyle(
color: Colors.white,
),
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your email',
prefixIcon: Icon(Icons.alternate_email,
color: Colors.white)),
),
),
SizedBox(
height: 8.0,
),
Material(
borderRadius: BorderRadius.circular(10.0),
elevation: 0.0,
color: Colors.white.withOpacity(0.2),
child: TextFormField(
cursorColor: Colors.white,
controller: password,
textAlign: TextAlign.center,
obscureText: hide,
// ignore: missing_return
validator: (String value) {
if (value.isEmpty) {
return "The password field cannot be empty";
}
},
style: TextStyle(
color: Colors.white,
),
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your password',
prefixIcon: Icon(
Icons.lock_outline,
color: Colors.white,
),
suffixIcon: IconButton(
icon: Icon(
!hide
? Icons.remove_red_eye_outlined
: Icons.remove_red_eye,
color: Colors.white,
),
onPressed: () {
setState(() {
hide = !hide;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 15, right: 8, bottom: 8),
child: InkWell(
onTap: () {
setState(() {
forgotPassword = true;
});
},
child: Text(
'Forgot Password?',
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white,
),
),
),
),
SizedBox(
height: 18.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
color: Colors.white,
borderRadius: BorderRadius.circular(30.0),
elevation: 2.0,
child: MaterialButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
performLogin();
}
},
minWidth: 200.0,
height: 42.0,
child: Text(
'Sign In',
style: TextStyle(color: Colors.black),
),
),
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'-OR-',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'sign in with',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 17),
),
),
googleSignInButton(),
],
))
: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Material(
borderRadius: BorderRadius.circular(10.0),
elevation: 0.0,
color: Colors.white.withOpacity(0.2),
child: Form(
key: _formKey,
child: TextFormField(
// ignore: missing_return
validator: (String value) {
if (value.isEmpty) {
return "please enter a value";
}
},
controller: email,
textAlign: TextAlign.center,
keyboardType: TextInputType.emailAddress,
style: TextStyle(
color: Colors.white,
),
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your email',
prefixIcon: Icon(Icons.alternate_email,
color: Colors.white)),
),
),
),
SizedBox(
height: 18.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
color: Colors.white,
borderRadius: BorderRadius.circular(30.0),
elevation: 2.0,
child: MaterialButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
ForgotPassword();
}
},
minWidth: 200.0,
height: 42.0,
child: Text(
'Continue',
style: TextStyle(color: Colors.black),
),
),
)),
Padding(
padding: const EdgeInsets.only(
top: 15, right: 8, bottom: 8),
child: Center(
child: InkWell(
onTap: () {
setState(() {
forgotPassword = false;
});
},
child: Text(
'Sign In',
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white,
),
),
),
),
),
],
),
],
),
));
}
// ignore: non_constant_identifier_names
void ForgotPassword() async {
setState(() {
isLoginPressed = true;
});
try {
await _auth.sendPasswordResetEmail(email: email.text);
setState(() {
isLoginPressed = false;
});
Fluttertoast.showToast(
msg: 'email sent successfully!!',
textColor: Colors.black,
backgroundColor: Colors.white);
showSuccessDialog(context, "email Sent",
'An email has been sent to your registered email id for resetting password',
() {
setState(() {
forgotPassword = false;
});
Navigator.pop(context);
});
} catch (e) {
setState(() {
isLoginPressed = false;
});
Fluttertoast.showToast(
msg: 'Please provide correct email',
textColor: Colors.black,
backgroundColor: Colors.white);
print(e);
}
}
Widget googleSignInButton() {
return GestureDetector(
onTap: () {
performGoogleLogin();
},
child: Center(
child: CircleAvatar(
radius: 35.0,
backgroundImage: AssetImage("assets/google.png"),
),
),
);
}
void performGoogleLogin() async {
setState(() {
isLoginPressed = true;
});
FirebaseUser user = await _authMethods.signInWithGoogle();
if (user != null) {
authenticateUser(user);
}
setState(() {
isLoginPressed = false;
});
}
void performLogin() async {
setState(() {
isLoginPressed = true;
});
FirebaseUser user = await _authMethods.signIn(email, password);
if (user != null) {
authenticateUser(user);
}
setState(() {
isLoginPressed = false;
});
}
void authenticateUser(FirebaseUser user) {
_authMethods.authenticateUser(user).then((isNewUser) {
setState(() {
isLoginPressed = false;
});
if (isNewUser) {
_authMethods.addDataToDb(user).then((value) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return HomeScreen();
}));
});
} else {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) {
return HomeScreen();
}));
}
});
}
}
此代码为两个用户显示相同的主页。如何根据用户转换此代码以显示 2 个不同的主页?更新:需要从 firebase db 检查一个字段,然后根据字段内的值将它们重定向到不同的页面。
解决方案
有多种方法可以做到这一点。我建议使用包含用户状态的StreamProvider
(来自)。Provider package
例如,您可以使用枚举:
enum UserState{
FIREBASE_AUTH,
GOOGLE
}
当用户使用特定方法登录时,您向流中添加一个事件,该事件将更新提供程序,从而根据流的值更新屏幕。
如果您想在应用程序的其他地方使用用户身份验证状态,我也会采用这种方法,您可以轻松访问它。
请让我知道这是否有帮助或我误解了你!
推荐阅读
- wordpress - 使用 .htaccess 的重定向不起作用
- coq - 为什么在 Coq 中,记录投影需要一个类型作为参数?
- unity3d - Unity-我似乎无法控制我的游戏对象的颜色
- xml - opc ua XML 文件创建
- jquery - 如果另一个元素具有类,则更改元素的可见性
- postgresql - 在不锁定表的情况下回收磁盘空间 - PostgreSQL 10
- api - 无法使用 ionic 2 中的 x-www-form-encoded 调用 post API
- c++ - Visual Studio 2010 单元测试:引用的项目类未被识别
- amazon-web-services - 将快照从 S3 还原到 AWS 托管弹性搜索时出现安全令牌服务异常
- azure-logic-apps - Azure 逻辑应用中的 EDIFACT DELFOR 解码