Firebase not detecting signed in users - flutter

am trying to create an app whereby at the initial step, users log in and after keying a username and password, the list of users should be reflected in Firebase Authentication screen. I am able to log in with username but the list of users logged in is not reflected...
Please help!
This is my login page code:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class Login extends StatefulWidget {
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _email, _password;
checkAuthentification() async {
_auth.authStateChanges().listen((user) {
if (user != null) {
print(user);
Navigator.pushReplacementNamed(context, "/");
}
});
}
#override
void initState() {
super.initState();
this.checkAuthentification();
}
login() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
try {
await _auth.signInWithEmailAndPassword(
email: _email, password: _password);
} catch (e) {
showError(e.message);
print(e);
}
}
}
showError(String errormessage) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('ERROR'),
content: Text(errormessage),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 300),
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Email';
},
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email)),
onSaved: (input) => _email = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.length < 6)
return 'Provide Minimum 6 Characters';
},
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
onSaved: (input) => _password = input),
),
SizedBox(height: 20),
RaisedButton(
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: login,
child: Text('LOGIN',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
color: Colors.orange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
)
],
),
),
),
],
),
),
));
}
}

Related

How can I upload the first name, last name, job and profile picture of the user?

Please Help me
I want to know how to upload the first name, last name, job, date of birth and a picture of the user in Flutter Null Safety
this is my signup
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:newlivenullsaf/pages/login.dart';
class Signup extends StatefulWidget {
#override
State<Signup> createState() => _SignupState();
}
class _SignupState extends State<Signup> {
final _formkey = GlobalKey<FormState>();
var email = '';
var password = '';
var confirmPassword = '';
#override
void dispose() {
emailController.dispose();
passwordController.dispose();
confirmPasswordController.dispose();
super.dispose();
}
bool isLoading = false;
final nameController = TextEditingController();
final emailController = TextEditingController();
final passwordController = TextEditingController();
final confirmPasswordController = TextEditingController();
registeration() async {
if (password == confirmPassword) {
try {
UserCredential userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
print(UserCredential);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.blueGrey,
content: Text(
'Registerd Successfully. Please Sign In ',
style: TextStyle(fontSize: 20.0),
),
),
);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const LoginPage(),
),
);
} on FirebaseAuthException catch (error) {
if (error.code == 'week-password') {
print('Password is too week');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.blueGrey,
content: Text(
'Password is too week ',
style: TextStyle(fontSize: 20.0, color: Colors.amberAccent),
),
),
);
} else if (error.code == 'email-already-in-use') {
print('Account is already exists');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.blueGrey,
content: Text(
'Account is already exists ',
style: TextStyle(fontSize: 20.0, color: Colors.amberAccent),
),
),
);
}
}
} else {
print('Password and Confirm Password does not match ');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.blueGrey,
content: Text(
'Password and Confirm Password does not match ',
style: TextStyle(fontSize: 20.0, color: Colors.amberAccent),
),
),
);
}
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
backgroundColor: Colors.white,
body: isLoading
? Center(
child: Container(
height: size.height / 20,
width: size.height / 20,
child: CircularProgressIndicator(),
),
)
: Form(
key: _formkey,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 20.0, horizontal: 20.0),
child: ListView(
children: [
Padding(
padding: const EdgeInsets.all(30.0),
child: Image.asset('images/signup.png'),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
decoration: const InputDecoration(
labelText: 'Name:',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.black26, fontSize: 15.0),
),
controller: nameController,
validator: (value) {
if (value == null || value.isNotEmpty) {
return 'Please Enter Your Name';
}
if (value.length > 4) {
return (' Name(Max. 4 Character)');
}
return null;
}),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
decoration: const InputDecoration(
labelText: 'Last Name:',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle: TextStyle(
color: Colors.black26, fontSize: 15.0),
),
controller: nameController,
validator: (value) {
if (value == null || value.isNotEmpty) {
return 'Please Enter Your Last Name';
}
if (value.length > 4) {
return ('Last Name(Max. 4 Character)');
}
return null;
}),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
decoration: const InputDecoration(
labelText: 'Email:',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.black26, fontSize: 15.0),
),
controller: emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Email';
} else if (!value.contains('#')) {
return 'Please Enter Valid Email';
}
return null;
},
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
obscureText: true,
decoration: const InputDecoration(
labelText: ' Password',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.black26, fontSize: 15.0),
),
controller: passwordController,
validator: (value) {
if (value == null ||
value.isEmpty ||
value.length < 6 ||
value.length > 14) {
return 'Please Enter Password';
}
return null;
},
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Confirm Password',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.black26, fontSize: 15.0),
),
controller: confirmPasswordController,
validator: (value) {
if (value == null ||
value.isEmpty ||
value.length < 6 ||
value.length > 14) {
return 'Please Confirm Password';
}
return null;
},
),
),
const SizedBox(
height: 10.0,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
if (_formkey.currentState!.validate()) {
setState(() {
email = emailController.text;
password = passwordController.text;
confirmPassword =
confirmPasswordController.text;
});
registeration();
}
},
child: const Text(
'Signup ',
style: TextStyle(fontSize: 18.0),
),
),
],
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Already Have An Account ?'),
TextButton(
onPressed: () {
Navigator.pushReplacement(
context,
PageRouteBuilder(
pageBuilder:
(context, animation1, animation2) =>
const LoginPage(),
transitionDuration:
const Duration(seconds: 0),
),
);
},
child: const Text('Login'),
),
],
),
),
],
),
),
),
);
}
}
this is my main
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:newlivenullsaf/pages/login.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initialization,
builder: (context, snapshot) {
if (snapshot.hasError) {
print('something wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
}
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter email & password',
theme: ThemeData(primarySwatch: Colors.blue),
home: const LoginPage(),
);
},
);
}
}
this is my login
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:newlivenullsaf/pages/forget_password.dart';
import 'package:newlivenullsaf/pages/signup.dart';
import 'package:newlivenullsaf/pages/user_main.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
var email = "";
var password = "";
final emailController = TextEditingController();
final passwordController = TextEditingController();
userLogin() async {
try {
await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => const UserMain()));
} on FirebaseAuthException catch (error) {
if (error.code == ' user-not-found') {
print('No user found for that email ');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.blueGrey,
content: Text(
'No user found for that email',
style: TextStyle(
fontSize: 18.0,
color: Colors.amber,
),
),
),
);
} else if (error.code == 'wrong-password') {
print('wrong password provided by the user');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.blueGrey,
content: Text(
'wrong password provided by the user',
style: TextStyle(
fontSize: 18.0,
color: Colors.amber,
),
),
),
);
}
}
}
#override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 20.0),
child: ListView(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('images/login.jpg'),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
decoration: const InputDecoration(
labelText: 'Email:',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.black26, fontSize: 15.0),
),
controller: emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Email';
} else if (!value.contains('#')) {
return 'Please Enter Valid Email';
}
return null;
}),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: TextFormField(
autofocus: false,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
labelStyle: TextStyle(fontSize: 20.0),
border: OutlineInputBorder(),
errorStyle:
TextStyle(color: Colors.black26, fontSize: 15.0),
),
controller: passwordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Password';
}
return null;
},
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
setState(() {
email = emailController.text;
password = passwordController.text;
});
userLogin();
}
},
child: const Text(
'Login',
style: TextStyle(fontSize: 18.0),
),
),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ForgotPass(),
),
);
},
child: const Text(
'Forget Password ?',
style: TextStyle(
fontSize: 12.0,
),
),
)
],
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Do Not Have Account ?'),
TextButton(
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
PageRouteBuilder(
pageBuilder: (context, a, b) => Signup(),
transitionDuration: const Duration(seconds: 0),
),
(route) => false);
},
child: const Text('Signup'),
),
],
),
),
],
),
),
),
);
}
}
Iused these packages
firebase_core: ^1.5.0
firebase_auth: ^3.0.2
I searched a lot and found a lot of codes and This code is the best I've found
please i need help quickly
I think you have to add (keep the auth like it is) cloud firestore and set a doc for each user contains his name , last name , job , profile pic etc...
so every user will have doc on cloud firestore and user on Auth
some sources :
to set the user in singUp page :
https://petercoding.com/firebase/2020/04/04/using-cloud-firestore-in-flutter/

flutter: how to autofill password in login form

I am trying when user check the checkbox it will autofill the password when user login again, i tried autofillhints in password textfield and wrap the widgets in AutofillGroup, but it is not working, when i login once and login again i am required to enter the password again.
and i am using api for fetching username and password.
here is my login code
class Login extends StatefulWidget {
Login({Key key, this.title}) : super(key: key);
final String title;
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
var name,password,token;
bool _passwordVisibilty;
void initState(){
_passwordVisibilty=false;
_formatDateTime();
}
String formattedDate;
String _formatDateTime() {
var now = new DateTime.now();
var formatter = new DateFormat('yyyy-MM-dd');
formattedDate = formatter.format(now);
print(formattedDate);
}
//svar localhostUrl="http://10.0.2.2:8000/login";
var herokuUrl="https://attendance-demo.herokuapp.com/login";
bool isSameuser = true;
final String username='';
final String email='';
final String designation='';
Future login() async {
try{
Dio dio=new Dio();
var data={
'username': user.username,
'password': user.password,
'date':formattedDate
};
await dio
.post(localhostUrlLogin,data: json.encode(data))
.then((onResponse) async {
//edited code here
SharedPreferences myPrefs=await SharedPreferences.getInstance();
String name=(onResponse.data['User']['username']);
String password=(onResponse.data['User']['password']);
if(name==""&&password==""){
myPrefs.setString('username', name);
myPrefs.setString('password', password);
}
else{
user.username=name;
user.password=password;
}
});}catch(e){
print("error "+e.toString());
showAlertDialog(BuildContext context) {
// Create button
Widget okButton = FlatButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
);
// Create AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Error",style: TextStyle(fontWeight: FontWeight.bold)),
content: Text("Invalid name or password.",style: TextStyle(fontSize: 17),),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
User user = User('', '');
//--------------------------
passwordtext(){
return TextFieldContainer(
child: TextFormField(
controller: TextEditingController(text: user.password),
autofillHints: [AutofillHints.password], //here is used autfodillhints
onEditingComplete: ()=>TextInput.finishAutofillContext(), //and i used this too
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(Icons.lock,color: Colors.blue,),
suffixIcon: GestureDetector(
onTap: () {
setState(() {
_passwordVisibilty = !_passwordVisibilty;
});
},
child: Icon(
_passwordVisibilty ? Icons.visibility : Icons.visibility_off,
),
),
labelText: 'Password'),
obscureText: !_passwordVisibilty,
onChanged: (value){
user.password=value;
},
),
);
}
return Scaffold(
body: SingleChildScrollView(
child: AutofillGroup(
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 155.0,
width: 200.0,
child: Image.asset(
"assets/image/company_logo.png",
fit: BoxFit.contain,
),
),
SizedBox(height: 50.0),
RoundedInputField(
labelText: "Username",icon: Icons.email,fontsize: textFontSize,
controller: TextEditingController(text: user.username),
onChanged: (value){
user.username=value;
},
),
SizedBox(height: 15.0),
passwordtext(),
SizedBox(
height: 0.0,
),
Align(
alignment: Alignment.centerLeft,
child:Row(children: <Widget>[
Checkbox(
checkColor: Colors.greenAccent,
activeColor: Colors.blue,
value: isSameuser,
onChanged: (bool newValue) {
if(newValue!=null){
setState(() {
isSameuser = newValue;
});
}},
),
Text("Save password?")
],)
),
SizedBox(
height: 23.0,
),
FlatButton(
color: Colors.blue[500],
textColor: Colors.white,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(buttonRoundRadius)),
child: Row(
children:<Widget>[
Expanded(child:
Text("Login",
textAlign: TextAlign.center,
style: TextStyle(fontSize: textFontSize),),)
,]),
onPressed: () {
login();
}
)
]),
),
),
),
))
);
}
}
Try this:
Use SharedPrefrences.
check if username and password is null, if it is null then store the username and password in the preferences.
if it is not null set the value of the textController to the values in the sharedPrefrences.

How to navigate from login to home page with Firebase flutter

In the welcome screen, I have two button which is login and register. For the first time, when i try to login to the login screen, it did not navigate to the Home Page. For the second try, I want to login again, it can't back to the login page (stuck at Welcome Screen). Can anyone help me? Thank you
Welcome Screen Code:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
final FirebaseAuth _auth = FirebaseAuth.instance;
navigateToLogin() async {
Navigator.pushReplacementNamed(context, "Login");
}
navigateToRegister() async {
Navigator.pushReplacementNamed(context, "SignUp");
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
children: <Widget>[
SizedBox(height: 35.0),
Container(
height: 400,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
SizedBox(height: 20),
RichText(
text: TextSpan(
text: 'Welcome to ',
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: Colors.orange),
children: <TextSpan>[
TextSpan(
text: 'MONGER!',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.orange))
])),
SizedBox(height: 10.0),
Text(
'Your Personal Money Tracker',
style: TextStyle(color: Colors.black),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
padding: EdgeInsets.only(left: 30, right: 30),
onPressed: navigateToLogin,
child: Text(
'LOGIN',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
color: Colors.orange),
SizedBox(width: 20.0),
RaisedButton(
padding: EdgeInsets.only(left: 30, right: 30),
onPressed: navigateToRegister,
child: Text(
'REGISTER',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
color: Colors.orange),
],
),
SizedBox(height: 20.0),
],
),
),
);
}
}
Login Page Code:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:monger_app/WelcomeScreen/signup.dart';
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _email, _password;
checkAuthentification() async {
_auth.authStateChanges().listen((user) {
if (user != null) {
print(user);
Navigator.pushReplacementNamed(context, "/");
}
});
}
#override
void initState() {
super.initState();
this.checkAuthentification();
}
login() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
try {
await _auth.signInWithEmailAndPassword(
email: _email, password: _password);
} catch (e) {
showError(e.message);
print(e);
}
}
}
showError(String errormessage) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('ERROR'),
content: Text(errormessage),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
navigateToSignUp() async {
Navigator.push(context, MaterialPageRoute(builder: (context) => SignUpPage()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
brightness: Brightness.light,
backgroundColor: Colors.white,
leading: IconButton(
onPressed: (){
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back_ios,
size: 20,
color: Colors.black,),
),
),
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 400,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Email';
},
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email)),
onSaved: (input) => _email = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.length < 6)
return 'Provide Minimum 6 Character';
},
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
onSaved: (input) => _password = input),
),
SizedBox(height: 20),
RaisedButton(
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: login,
child: Text('LOGIN',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
color: Colors.orange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
)
],
),
),
),
GestureDetector(
child: Text('Create an Account?'),
onTap: navigateToSignUp,
)
],
),
),
));
}
}
Sign Up code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class SignUpPage extends StatefulWidget {
#override
_SignUpPageState createState() => _SignUpPageState();
}
class _SignUpPageState extends State<SignUpPage> {
FirebaseAuth _auth = FirebaseAuth.instance;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _username, _email, _password;
checkAuthentication() async {
_auth.authStateChanges().listen((user) async {
if (user != null) {
Navigator.pushReplacementNamed(context, "/");
}
});
}
#override
void initState() {
super.initState();
this.checkAuthentication();
}
signUp() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
try {
UserCredential user = await _auth.createUserWithEmailAndPassword(
email: _email, password: _password);
if (user != null) {
// UserUpdateInfo updateuser = UserUpdateInfo();
// updateuser.displayName = _name;
// user.updateProfile(updateuser);
await _auth.currentUser.updateProfile(displayName: _username);
// await Navigator.pushReplacementNamed(context,"/") ;
}
} catch (e) {
showError(e.message);
print(e);
}
}
}
showError(String errormessage) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('ERROR'),
content: Text(errormessage),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
brightness: Brightness.light,
backgroundColor: Colors.white,
leading: IconButton(
onPressed: (){
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back_ios,
size: 20,
color: Colors.black,),
),
),
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 400,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Username';
},
decoration: InputDecoration(
labelText: 'Username',
prefixIcon: Icon(Icons.person),
),
onSaved: (input) => _username = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Email';
},
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email)),
onSaved: (input) => _email = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.length < 6)
return 'Provide Minimum 6 Character';
},
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
onSaved: (input) => _password = input),
),
SizedBox(height: 20),
RaisedButton(
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: signUp,
child: Text('SignUp',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
color: Colors.orange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
)
],
),
),
),
],
),
),
));
}
}
Main Code:
import 'package:flutter/material.dart';
import 'package:monger_app/WelcomeScreen/login.dart';
import 'package:monger_app/WelcomeScreen/signup.dart';
import 'package:monger_app/WelcomeScreen/welcome_screen.dart';
import 'package:monger_app/page/root.dart';
import 'package:monger_app/theme/colors.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: primary
),
debugShowCheckedModeBanner: false,
home:
WelcomeScreen(),
routes: <String,WidgetBuilder>{
"Login" : (BuildContext context)=>LoginPage(),
"SignUp":(BuildContext context)=>SignUpPage(),
"start":(BuildContext context)=>Root(),
},
);
}
}
HomePage Code
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:monger_app/page/setting.dart';
import 'package:monger_app/theme/colors.dart';
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
import 'package:monger_app/page/transaction.dart';
import 'package:monger_app/page/statistics.dart';
import 'package:monger_app/page/account.dart';
import 'package:monger_app/page/record.dart';
import 'package:firebase_auth/firebase_auth.dart';
class Root extends StatefulWidget {
#override
_RootState createState() => _RootState();
}
class _RootState extends State<Root> {
final FirebaseAuth _auth = FirebaseAuth.instance;
User user;
bool isloggedin = false;
checkAuthentification() async {
_auth.authStateChanges().listen((user) {
if (user == null) {
Navigator.of(context).pushReplacementNamed("start");
}
});
}
int pageIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: getBody(),
bottomNavigationBar: getFooter(),
floatingActionButton: FloatingActionButton(
onPressed: (){
setTabs(4);
},
child: Icon(Icons.add, size: 25),
backgroundColor: primary,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
Widget getBody(){
return IndexedStack(
index: pageIndex,
children: [
Transaction(),
Statistics(),
Account(),
Settings(),
Record()
],
);
}
Widget getFooter(){
List<IconData> iconItems = [
Ionicons.md_bookmarks,
Ionicons.md_stats,
Ionicons.md_wallet,
Ionicons.ios_settings,
];
return AnimatedBottomNavigationBar(
activeColor: primary,
splashColor: secondary,
inactiveColor: Colors.black.withOpacity(0.5),
icons: iconItems,
activeIndex: pageIndex,
gapLocation: GapLocation.center,
notchSmoothness: NotchSmoothness.softEdge,
leftCornerRadius: 10,
iconSize: 25,
rightCornerRadius: 10,
onTap: (index) {
setTabs(index);
});
}
setTabs(index) {
setState(() {
pageIndex = index;
});
}
}
You have this code:
Navigator.pushReplacementNamed(context, "/");
but you do not have the named route "/" registered.
From your code, your Home Page is registered as "start".
So you should update the name of the route to "start" and that should work.
Your updated code should be as below:
Navigator.pushReplacementNamed(context, "start");

StreamProvider is not responding to changed value of stream

I am making a flutter application where i need to register into firebase.
First I have SignInPage() which uses Navigator to redirect to ResidentRegister().Here is the form for registering into the application. The problem is the ResidentRegister() page is not getting redirected to HomeScreen() upon successful Authentication of the user. The user is properly registered into the firebase and HomeScreen() appears after hotrestart of the application. I have used StreamProvider for the purpose which should listen to a stream of type 'Resident' which is my User data model based on whether it is null or not in the Wrapper() class. In the 'Wrapper' class, the stream is getting 'instance of resident'(when I print the value of resident variable), but the else block is not getting executed. This is probably happening due to usage of Navigator as when I remove the first screen that is SignInPage(), the ResidentRegister() screen is successfully getting redirected to HomeScreen(). I don't know why this happens as I have wrapped the MaterialApp to StreamProvider widget.
Any help would be appreciated
Thanks!
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamProvider<Resident>(
create: (_)=> AuthService().resident,
child: Consumer<Resident>(
builder: (context, resident, _)
{
return MaterialApp(
home: (user != null) ? HomeScreen() : SignInPage(),
);
},
),
);
}
}
class SignInPage extends StatelessWidget {
SignInPage({this.title});
final String title;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('JNMCH eLogBook'),
centerTitle: true,
),
body: SizedBox.expand(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Sign In',
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.w300,
fontSize: 65,
),),
SizedBox(height: 35,),
CustomButton(text: 'Sign In as a Resident', onPressed: ()=> Navigator.pushNamed(context, '/residentRegister')),
SizedBox(height:8.0),
CustomButton(text: 'Sign In as a Mentor', onPressed: () => Navigator.pushNamed(context,'/mentorSignIn')),
],
),
),
);
}
}
class ResidentRegister extends StatefulWidget {
#override
_ResidentRegisterState createState() => _ResidentRegisterState();
}
class _ResidentRegisterState extends State<ResidentRegister> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
String _email;
String _password;
String _confirmPassword;
String _error = '';
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text('Register as a Resident'),
),
body: SingleChildScrollView(
child: Stack(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 80.0, horizontal: 40.0),
child: Card(
color: Colors.white,
elevation: 8.0,
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(height: 20,),
Text('Register',
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.w300,
fontSize: 65,
),
),
SizedBox(height: 35,),
TextFormField(
validator: (val) => val.isEmpty ? 'Enter an email' : null,
decoration: InputDecoration(
hintText: 'Email'
),
onChanged: (value) {
setState(() {
_email = value;
});
},
),
SizedBox(height: 20,),
TextFormField(
validator: (val) => val.length < 6 ? 'Enter a password 6+ char long' : null,
decoration: InputDecoration(
hintText: 'Password'
),
obscureText: true,
onChanged: (value) {
setState(() {
_password = value;
});
},
),
SizedBox(height: 20,),
TextFormField(
validator: (val) => val!=_password ? 'Confirm Password must be same as password' : null,
decoration: InputDecoration(
hintText: 'Confirm Password'
),
obscureText: true,
onChanged: (value) {
setState(() {
_confirmPassword = value;
});
},
),
SizedBox(height: 20,),
Padding(
padding: const EdgeInsets.all(0),
child: ButtonTheme(
minWidth: 150,
height: 50,
child: RaisedButton(onPressed: () async {
if(_formKey.currentState.validate()){
dynamic result = await _auth.register( _email,_password);
if(result == null){
setState(() {
_error = 'Please supply a valid email';
});
}
}
},
color: Colors.teal,
child:
Text(
'Submit',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20,),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28.0),
side: BorderSide(color: Colors.teal[100]),
),
),
),
),
SizedBox(height: 20,),
Text(_error, style: TextStyle(
fontSize: 14.0,
color: Colors.red,
),),
SizedBox(height: 20,),
FlatButton(
color: Colors.white,
textColor: Colors.grey[600],
disabledColor: Colors.black,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
splashColor: Colors.teal,
onPressed: () {
Navigator.pop(context);
},
child: Text(
"Already have an account? Sign In!",
style: TextStyle(fontSize: 16.0),
),
)
],
),
),
),
),
),
],
),
),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
actions: <Widget> [
FlatButton.icon(
onPressed: ()async {
await _auth.signOut();
},
icon: Icon(Icons.person,color: Colors.white,),
label: Text('Sign Out', style: TextStyle(color: Colors.white),)),
],
),
);
}
}
class AuthService{
final FirebaseAuth _auth = FirebaseAuth.instance;
// create resident user object based on Firebase User
Resident _residentFromFirebaseUser(FirebaseUser user){
return user!=null ? Resident(uid: user.uid) : null;
}
//auth change user stream
Stream<Resident> get resident {
return _auth.onAuthStateChanged
.map(_residentFromFirebaseUser);
}
//register with email and password
Future register(String email, String password) async{
try{
AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
print(user);
return _residentFromFirebaseUser(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 Resident{
final String uid;
Resident({ this.uid });
}
I believe you're using StreamProvider incorrectly. It shouldn't be:
StreamProvider<Resident>.value(value: ...)
Instead, try using:
StreamProvider<Resident>(
create: (_) => AuthService().resident,
child: Consumer<Resident>(
builder: (context, resident, _) {
// TODO: return home page or sign in page based on data
},
),
);
That should subscribe to the stream and rebuild on new events.

Flutter: form shifts when validation is false

i'm building a UI for a login form with validation.
Here is the page:
I'm overall very pleased with the look of the page and it works fine. There is just one exception: when the user inputs invalid parameters in the fields (one or more) the form shifts and the button responsable for the password visibility is not centered anymore.
I searched online and they suggest to wrap it in an Expanded widget, but it doesn't solve my problem.
Here's a image, that shows the problem:
Here is the code:
import 'package:email_validator/email_validator.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:client/providers/cloudfirestore_provider.dart';
import 'package:client/screens/forgotpass_screen.dart';
import 'package:client/screens/register_screen.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
FirebaseAuth auth = FirebaseAuth.instance;
final _formKey = GlobalKey<FormState>();
final email = TextEditingController();
final password = TextEditingController();
bool _obscureText = true;
IconData iconData = Icons.visibility;
var isLoading = false;
final focus = FocusNode();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (ctx) => SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.yellow,
width: double.infinity,
height: MediaQuery.of(context).padding.top,
),
Stack(
alignment: Alignment.center,
children: [
Container(
color: Colors.yellow,
width: double.infinity,
height: (MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top) *
0.4,
),
ClipRRect(
borderRadius: BorderRadius.circular(100.0),
child: Container(
child: Image.asset('assets/images/logo.jpg'),
height: 150,
width: 150,
),
),
],
),
Container(
height: (MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top) *
0.6,
padding: EdgeInsets.symmetric(vertical: 30, horizontal: 60),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Hi, there!",
style: TextStyle(fontSize: 20, color: Colors.grey[900]),
),
Container(
height: 210,
child: Form(
key: _formKey,
child: Column(
children: [
Expanded(
child: TextFormField(
textInputAction: TextInputAction.next,
onFieldSubmitted: (v) {
FocusScope.of(context).requestFocus(focus);
},
controller: email,
decoration: InputDecoration(labelText: "Email"),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (EmailValidator.validate(value)) {
return null;
}
return "Please enter a valid email";
},
),
),
Expanded(
child: Stack(
children: [
TextFormField(
focusNode: focus,
controller: password,
decoration:
InputDecoration(labelText: "Password"),
obscureText:
_obscureText, // create little eye to show password
validator: (value) {
if (value.length < 6) {
return 'Minimum 6 characters';
}
return null;
},
),
IconButton(
icon: Icon(iconData),
onPressed: () {
setState(
() {
_obscureText = !_obscureText;
if (iconData == Icons.visibility) {
iconData = Icons.visibility_off;
} else {
iconData = Icons.visibility;
}
},
);
})
],
alignment: Alignment.bottomRight,
),
),
SizedBox(
height: 20,
),
Container(
width: 200,
height: 50,
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
),
color: Colors.deepOrange,
textColor: Colors.white,
onPressed: () async {
Scaffold.of(ctx).hideCurrentSnackBar();
setState(() {
isLoading = true;
});
if (_formKey.currentState.validate()) {
login(email, password) async {
try {
await FirebaseAuth.instance.signOut();
await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: email.text,
password: password.text);
if (FirebaseAuth.instance.currentUser
.emailVerified ==
false)
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(
"Please verify your email."),
),
);
else
Scaffold.of(ctx).showSnackBar(
SnackBar(
content:
Text("Logging you in ..."),
),
);
setState(() {
isLoading = false;
});
} catch (e) {
print(e.toString());
if (e.toString() ==
"[firebase_auth/wrong-password] The password is invalid or the user does not have a password.") {
Scaffold.of(ctx)
.hideCurrentSnackBar();
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(
"The password is incorrect."),
),
);
} else if (e.toString() ==
"[firebase_auth/user-not-found] There is no user record corresponding to this identifier. The user may have been deleted.") {
Scaffold.of(ctx)
.hideCurrentSnackBar();
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(
"There is no email adress connected to this account."),
),
);
} else if (e.toString() ==
"[firebase_auth/too-many-requests] We have blocked all requests from this device due to unusual activity. Try again later.") {
Scaffold.of(ctx)
.hideCurrentSnackBar();
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(
"We have blocked all requests from this device due to unusual activity. Try again later."),
),
);
} else {
Scaffold.of(ctx)
.hideCurrentSnackBar();
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(
"Pls check your internet connection and try again."),
),
);
}
setState(() {
isLoading = false;
});
}
}
await login(email, password).whenComplete(
() => CloudFirestoreProvider().addUser(
email.text,
password.text,
));
} else
setState(() {
isLoading = false;
});
},
child: (isLoading)
? CircularProgressIndicator(
backgroundColor: Colors.white,
)
: Text('Submit',
style: TextStyle(fontSize: 22)),
),
),
],
),
),
),
Expanded(
child: Container(
alignment: Alignment.bottomCenter,
child: Row(
children: [
FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ForgotPassScreen(),
),
);
},
child: Text(
"Forgot Password ?",
style: TextStyle(color: Colors.deepOrange),
),
),
Expanded(child: SizedBox()),
FlatButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RegisterScreen(),
),
);
},
child: Text(
"Register",
style: TextStyle(color: Colors.deepOrange),
),
),
],
),
),
)
],
),
),
],
),
),
),
);
}
}
EDIT:
I tried swapping the Stack method for the suffixIcon suggested. And it works except for the position of the Icon that is off-centred.
Here's the updated code:
Expanded(
child: TextFormField(
focusNode: focus,
controller: password,
decoration: InputDecoration(
labelText: "Password",
suffixIcon: IconButton(
color: Colors.grey[900],
icon: Icon(iconData),
onPressed: () {
setState(
() {
_obscureText = !_obscureText;
if (iconData ==
Icons.visibility) {
iconData = Icons.visibility_off;
} else {
iconData = Icons.visibility;
}
},
);
})),
obscureText:
_obscureText, // create little eye to show password
validator: (value) {
if (value.length < 6) {
return 'Minimum 6 characters';
}
return null;
},
),
),
Put your icon in the sufficient property of the input Decoration on your password text field.
inputDecoration(suffixIcon: IconButton())