When the user starts my app the first time, he can toggle between the registration form and the sign in form. After completing one of this forms, he should see the loading screen until the user is created or signed in. In my case, unfortunately, the loading screen doesn't disappear, although the user is created.
How can I fix this problem?
the sign in form:
class SignIn extends StatefulWidget {
final Function toggleView;
SignIn({this.toggleView});
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
bool loading = false;
// text field state
String email = '';
String password = '';
String error = '';
static const color = const Color(0xFF2F80ED);
#override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: Stack(
children: <Widget>[
Container(
child: Positioned(
top: 0,
right: 0,
child: Image.asset(
'assets/canvas-1-ws.png',
),
),
),
Positioned(
top: 25.0,
left: 5.0,
child: IconButton(
icon: Icon(
Icons.close,
color: Colors.black,
size: 35.0,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Welcome(),
),
);
},
),
),
Container(
child: Positioned(
bottom: 0,
left: 0,
child: Image.asset(
'assets/canvas-2-ws.png',
),
),
),
Center(
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
left: 50.0,
right: 50.0,
),
child: Container(
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Login',
style: TextStyle(
color: Colors.black,
fontFamily: 'Roboto Black',
fontSize: 35.0,
),
),
SizedBox(
height: 30.0,
),
TextFormField(
style: TextStyle(
fontFamily: 'Roboto Light',
color: Colors.black,
),
cursorColor: Colors.black,
decoration: InputDecoration(
fillColor: Colors.black,
hintText: 'Email',
hintStyle: TextStyle(
fontFamily: 'Roboto Light',
color: Colors.black,
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
width: 1.0,
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
width: 1.0,
),
),
),
validator: (val) => val.isEmpty
? 'Bitte gültige Email'
: null,
onChanged: (val) {
setState(() => email = val);
},
),
SizedBox(
height: 20.0,
),
TextFormField(
style: TextStyle(
fontFamily: 'Roboto Light',
color: Colors.black,
),
cursorColor: Colors.black,
decoration: InputDecoration(
fillColor: Colors.black,
hintText: 'Passwort',
hintStyle: TextStyle(
fontFamily: 'Roboto Light',
color: Colors.black,
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
width: 1.0,
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
width: 1.0,
),
),
),
obscureText: true,
validator: (val) => val.isEmpty
? 'Bitte gültiges Passwort'
: null,
onChanged: (val) {
setState(() => password = val);
}),
SizedBox(
height: 45.0,
),
ButtonTheme(
minWidth: 200,
height: 50,
child: RaisedButton(
elevation: 0,
color: color,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
side: BorderSide(color: color),
),
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: color,
spreadRadius: 10.0,
blurRadius: 20.0,
offset: Offset(0, 3),
),
],
),
child: Text(
'Login',
style: TextStyle(
fontFamily: 'Roboto Light',
fontSize: 25.0),
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result = await _auth
.signInWithEmailAndPassword(
email, password);
if (result == null) {
setState(() {
error = 'Falsche Email/Password';
loading = false;
});
}
}
},
),
),
],
),
),
),
),
],
),
),
],
),
);
}
}
the registration form is almost similar...
the file, where the user can toggle between the forms:
class Welcome extends StatefulWidget {
final Function toggleView;
Welcome({this.toggleView});
#override
_WelcomeState createState() => _WelcomeState();
}
class _WelcomeState extends State<Welcome> {
static const color = const Color(0xFF2F80ED);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: <Widget>[
Positioned(
top: 0,
right: 0,
child: Image.asset('assets/canvas-1-ws.png'),
),
Positioned(
bottom: 0,
left: 0,
child: Image.asset('assets/canvas-2-ws.png'),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/Skiclublogo_transparent.png',
scale: 4,
),
SizedBox(
height: 40.0,
),
ButtonTheme(
minWidth: 200,
height: 50,
child: RaisedButton(
elevation: 0,
color: color,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
side: BorderSide(color: color),
),
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: color,
spreadRadius: 10.0,
blurRadius: 20.0,
offset: Offset(0, 3),
),
],
),
child: Text(
'Registrieren',
style: TextStyle(
fontFamily: 'Roboto Light', fontSize: 25.0),
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Register(),
),
);
}),
),
SizedBox(
height: 40.0,
),
ButtonTheme(
minWidth: 200,
height: 50,
child: RaisedButton(
elevation: 0,
color: color,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
side: BorderSide(color: color),
),
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: color,
spreadRadius: 10.0,
blurRadius: 20.0,
offset: Offset(0, 3),
),
],
),
child: Text(
'Login',
style: TextStyle(
fontFamily: 'Roboto Light', fontSize: 25.0),
),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SignIn(),
),
);
}),
),
],
),
),
],
),
);
}
}
the auth file, where the user is created or logged in:
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on FirrebaseUser
User _userFromFirebaseUser(FirebaseUser user) {
return user != null ? User(uid: user.uid) : null;
}
// auth change user stream
Stream<User> get user {
return _auth.onAuthStateChanged.map(_userFromFirebaseUser);
}
// sign in anonmously
Future signInAnon() async {
try {
AuthResult result = await _auth.signInAnonymously();
FirebaseUser user = result.user;
// create a new document for the user with the uid
await DatabaseService(uid: user.uid).updateUserData(
user.displayName, user.email, user.photoUrl, user.uid);
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// sign in email & password
Future signInWithEmailAndPassword(String email, String password) async {
try {
AuthResult result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// register with email & password
Future registerWithEmailAndPassword(
String email, String password, String name) async {
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
// update user info
UserUpdateInfo userUpdateInfo = UserUpdateInfo();
userUpdateInfo.displayName = name;
await user.updateProfile(userUpdateInfo);
await user.reload();
user = await FirebaseAuth.instance.currentUser();
// create a new document for the user with the uid
await DatabaseService(uid: user.uid).updateUserData(
user.displayName, user.email, user.photoUrl, user.uid);
return _userFromFirebaseUser(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;
}
}
// current user
void inputData() async {
final FirebaseUser user = await _auth.currentUser();
final uid = user.uid;
// here you write the codes to input the data into firestore
}
}
the wrapper file, where the app checks if the user is new:
class Wrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print(user);
// return either Home or Authenticate widget
if (user == null) {
return Welcome();
} else {
return DrawerNav();
}
}
}
the loading screen file:
class Loading extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Center(
child: SpinKitWave(
color: Colors.black,
size: 50.0,
),
),
);
}
}
Thank you very much when you've read through all of this!
You don't always call setState after the user is created.
This will work
onPressed: (){ if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result = await _auth
.signInWithEmailAndPassword(
email, password);
setState(() => loading = false);
if (result == null) {
setState(() {
error = 'Falsche Email/Password';
});
}
}},
Ill explain you my friend
set a boolean variable named loading
loading = false;
if loading is true display loading screen else display your form ui using ternary operator
while creating user change the state of loading so that loading screen will appear
setState(() { loading=true; });
after user is created change the state of loading again to false
setState(() { loading=false; });
This is the template in build function
loading==false?yourui():loading()
Related
My Flutter is not able to connect to my Cloud Firestore. Everything works fine, I can register, I can login, and the user is saved in the auth in Firebase. But the Cloud Firestore is not recieving any data from the registration_page.dart
My code to add the user to firestore
// Adding User to Cloud Firestore
CollectionReference users = FirebaseFirestore.instance.collection('users');
Future<void> addUser() {
return users
.add({
'email': email,
'password': password,
'confirmPassword': confirmPassword
})
.then((value) => print('User Added'))
.catchError((error) => print('Failed to Add user: $error'));
}
This is my onPressed for the signUpButton
onPressed: () {
// Validate returns true if the form is valid, otherwise false.
if (_formKey.currentState!.validate()) {
setState(() {
email = emailController.text;
password = passwordController.text;
confirmPassword = confirmPasswordController.text;
passwordRegistration();
addUser();
clearText();
});
}
},
This is my full code of registration_page.dart
// ignore_for_file: prefer_const_constructors, avoid_print
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:list_list_2/constants/color_constant.dart';
import 'package:list_list_2/page/login/login_page.dart';
class RegistrationPage extends StatefulWidget {
const RegistrationPage({Key? key}) : super(key: key);
#override
State<RegistrationPage> createState() => _RegistrationPageState();
}
class _RegistrationPageState extends State<RegistrationPage> {
//Form Key
final _formKey = GlobalKey<FormState>();
var email = "";
var password = "";
var confirmPassword = "";
final emailController = TextEditingController();
final passwordController = TextEditingController();
final confirmPasswordController = TextEditingController();
#override
void dispose() {
// Clean up the controller when the widget is disposed.
emailController.dispose();
passwordController.dispose();
confirmPasswordController.dispose();
super.dispose();
}
clearText() {
emailController.clear();
passwordController.clear();
confirmPasswordController.clear();
}
passwordRegistration() async {
if (password == confirmPassword) {
try {
UserCredential userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
print(userCredential);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: kSoftLimeGreen,
content: Text(
"Registered Successfully. Please Login..",
style: TextStyle(fontSize: 20.0),
),
),
);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => LoginPage(),
),
);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print("Password Provided is too Weak");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: lightOrange,
content: Text(
"Password Provided is too Weak",
style: GoogleFonts.dongle(fontSize: 18.0, color: blackColor),
),
),
);
} else if (e.code == 'email-already-in-use') {
print("Account Already exists");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: lightOrange,
content: Text(
"Account Already exists",
style: GoogleFonts.dongle(fontSize: 18.0, color: blackColor),
),
),
);
}
}
} else {
print("Password and Confirm Password doesn't match");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: lightOrange,
content: Text(
"Password and Confirm Password doesn't match",
style: GoogleFonts.dongle(fontSize: 16.0, color: blackColor),
),
),
);
}
}
// Adding User to Cloud Firestore
CollectionReference users = FirebaseFirestore.instance.collection('users');
Future<void> addUser() {
return users
.add({
'email': email,
'password': password,
'confirmPassword': confirmPassword
})
.then((value) => print('User Added'))
.catchError((error) => print('Failed to Add user: $error'));
}
#override
Widget build(BuildContext context) {
//Email Field
final emailField = TextFormField(
autofocus: false,
controller: emailController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Email';
} else if (!value.contains('#')) {
return 'Please Enter Valid Email';
}
return null;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
//Password Field
final passwordField = TextFormField(
autofocus: false,
controller: passwordController,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please Enter Password';
}
return null;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.vpn_key),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
//Confirm Password
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordController,
obscureText: true,
validator: (value) {
if (confirmPasswordController.text != passwordController.text) {
return "Password Don't Match!";
}
return null;
},
textInputAction: TextInputAction.done,
decoration: InputDecoration(
prefixIcon: Icon(Icons.vpn_key),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Confirm Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
//Sign Up Button
final signUpButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(50),
child: Container(
width: MediaQuery.of(context).size.width,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
gradient: LinearGradient(
colors: const [kDarkModerateCyan, kModerateCyan],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
child: Material(
borderRadius: BorderRadius.circular(50),
color: Colors.transparent,
child: Center(
child: MaterialButton(
child: Text(
"SignUp",
textAlign: TextAlign.center,
style: GoogleFonts.dongle(
fontSize: 28,
color: defaultColor,
fontWeight: FontWeight.bold,
),
),
padding: EdgeInsets.fromLTRB(20, 10, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
// Validate returns true if the form is valid, otherwise false.
if (_formKey.currentState!.validate()) {
setState(() {
email = emailController.text;
password = passwordController.text;
confirmPassword = confirmPasswordController.text;
passwordRegistration();
addUser();
clearText();
});
}
},
),
),
),
),
);
//Reset Button
final resetButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(50),
child: Container(
width: MediaQuery.of(context).size.width,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: greyColor,
),
child: Material(
borderRadius: BorderRadius.circular(50),
color: Colors.transparent,
child: Center(
child: MaterialButton(
child: Text(
"Reset",
textAlign: TextAlign.center,
style: GoogleFonts.dongle(
fontSize: 28,
color: defaultColor,
fontWeight: FontWeight.bold,
),
),
padding: EdgeInsets.fromLTRB(20, 10, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () => {clearText()},
),
),
),
),
);
return Scaffold(
backgroundColor: whiteColor,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: kVeryDarkCyan,
),
onPressed: () {
//passing this to our root
Navigator.of(context).pop();
},
),
),
body: Stack(
children: <Widget>[
SingleChildScrollView(
child: Column(
children: [
Material(
borderRadius: BorderRadius.circular(55),
color: kDarkModerateCyan,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 180,
child: SvgPicture.asset(
"assets/logo.svg",
fit: BoxFit.contain,
),
),
emailField,
SizedBox(
height: 15,
),
passwordField,
SizedBox(
height: 15,
),
confirmPasswordField,
SizedBox(
height: 15,
),
signUpButton,
SizedBox(
height: 15,
),
resetButton,
SizedBox(
height: 15,
),
],
),
),
),
),
],
),
),
],
),
);
}
}
And this is my GitHub https://github.com/MonsterEat90/List-List
I am trying to added role type for users (Normal User, Admin user, Doctor user)
Where each user once he login he has his own screen different than other.
Suppose you are in the login screen and press the login button. In this case the user should be navigated inside the app and we should pop the login screen from the app. Adding if the user is an Admin types, he should be shown screen 2 vs screen 3 or X for other user roles.
Now for a logged in user, when they logout, the entire state of the app should be refreshed and a login screen should be shown.
Tired many ways keep getting my application crashing
Keep in mind I am new in flutter programing.
This is user
class User {
String email;
String name;
String userID;
String profilePictureURL;
String appIdentifier;
User({
this.email = '',
this.name = '',
this.userID = '',
this.profilePictureURL = '',
}) : this.appIdentifier = 'Flutter Login Screen ${Platform.operatingSystem}';
factory User.fromJson(Map<String, dynamic> parsedJson) {
return new User(
email: parsedJson['email'] ?? '',
name: parsedJson['name'] ?? '',
userID: parsedJson['id'] ?? parsedJson['userID'] ?? '',
profilePictureURL: parsedJson['profilePictureURL'] ?? '');
}
Map<String, dynamic> toJson() {
return {
'email': this.email,
'name': this.name,
'id': this.userID,
'profilePictureURL': this.profilePictureURL,
'appIdentifier': this.appIdentifier
};
}
}
User Authentication
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart' as auth;
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:flutter_login_screen/constants.dart';
import 'package:flutter_login_screen/model/user.dart';
import 'package:flutter_login_screen/services/helper.dart';
class FireStoreUtils {
static FirebaseFirestore firestore = FirebaseFirestore.instance;
static Reference storage = FirebaseStorage.instance.ref();
static Future<User?> getCurrentUser(String uid) async {
DocumentSnapshot<Map<String, dynamic>> userDocument =
await firestore.collection(USERS).doc(uid).get();
if (userDocument.data() != null && userDocument.exists) {
return User.fromJson(userDocument.data()!);
} else {
return null;
}
}
static Future<User> updateCurrentUser(User user) async {
return await firestore
.collection(USERS)
.doc(user.userID)
.set(user.toJson())
.then((document) {
return user;
});
}
static Future<String> uploadUserImageToFireStorage(
File image, String userID) async {
Reference upload = storage.child("images/$userID.png");
UploadTask uploadTask = upload.putFile(image);
var downloadUrl =
await (await uploadTask.whenComplete(() {})).ref.getDownloadURL();
return downloadUrl.toString();
}
/// login with email and password with firebase
static Future<dynamic> loginWithEmailAndPassword(
String email, String password) async {
try {
auth.UserCredential result = await auth.FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
DocumentSnapshot<Map<String, dynamic>> documentSnapshot =
await firestore.collection(USERS).doc(result.user?.uid ?? '').get();
User? user;
if (documentSnapshot.exists) {
user = User.fromJson(documentSnapshot.data() ?? {});
}
return user;
} on auth.FirebaseAuthException catch (exception, s) {
print(exception.toString() + '$s');
switch ((exception).code) {
case 'invalid-email':
return 'Email address is malformed.';
case 'wrong-password':
return 'Wrong password.';
case 'user-not-found':
return 'No user corresponding to the given email address.';
case 'user-disabled':
return 'This user has been disabled.';
case 'too-many-requests':
return 'Too many attempts to sign in as this user.';
}
return 'Unexpected firebase error, Please try again.';
} catch (e, s) {
print(e.toString() + '$s');
return 'Login failed, Please try again.';
}
}
static loginWithFacebook() async {
FacebookAuth facebookAuth = FacebookAuth.instance;
bool isLogged = await facebookAuth.accessToken != null;
if (!isLogged) {
LoginResult result = await facebookAuth
.login();
if (result.status == LoginStatus.success) {
// you are logged
AccessToken? token = await facebookAuth.accessToken;
return await handleFacebookLogin(
await facebookAuth.getUserData(), token!);
}
} else {
AccessToken? token = await facebookAuth.accessToken;
return await handleFacebookLogin(
await facebookAuth.getUserData(), token!);
}
}
static handleFacebookLogin(
Map<String, dynamic> userData, AccessToken token) async {
auth.UserCredential authResult = await auth.FirebaseAuth.instance
.signInWithCredential(
auth.FacebookAuthProvider.credential(token.token));
User? user = await getCurrentUser(authResult.user?.uid ?? '');
if (user != null) {
user.profilePictureURL = userData['picture']['data']['url'];
user.name = userData['name'];
user.email = userData['email'];
dynamic result = await updateCurrentUser(user);
return result;
} else {
user = User(
email: userData['email'] ?? '',
name: userData['name'] ?? '',
profilePictureURL: userData['picture']['data']['url'] ?? '',
userID: authResult.user?.uid ?? '');
String? errorMessage = await firebaseCreateNewUser(user);
if (errorMessage == null) {
return user;
} else {
return errorMessage;
}
}
}
static Future<String?> firebaseCreateNewUser(User user) async =>
await firestore
.collection(USERS)
.doc(user.userID)
.set(user.toJson())
.then((value) => null, onError: (e) => e);
static firebaseSignUpWithEmailAndPassword(
String emailAddress,
String password,
File? image,
String name,
) async {
try {
auth.UserCredential result = await auth.FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: emailAddress, password: password);
String profilePicUrl = '';
if (image != null) {
await updateProgress('Uploading image, Please wait...');
profilePicUrl =
await uploadUserImageToFireStorage(image, result.user?.uid ?? '');
}
User user = User(
email: emailAddress,
name: name,
userID: result.user?.uid ?? '',
profilePictureURL: profilePicUrl);
String? errorMessage = await firebaseCreateNewUser(user);
if (errorMessage == null) {
return user;
} else {
return 'Couldn\'t sign up for firebase, Please try again.';
}
} on auth.FirebaseAuthException catch (error) {
print(error.toString() + '${error.stackTrace}');
String message = 'Couldn\'t sign up';
switch (error.code) {
case 'email-already-in-use':
message = 'Email already in use, Please pick another email!';
break;
case 'invalid-email':
message = 'Enter valid e-mail';
break;
case 'operation-not-allowed':
message = 'Email/password accounts are not enabled';
break;
case 'weak-password':
message = 'Password must be more than 5 characters';
break;
case 'too-many-requests':
message = 'Too many requests, Please try again later.';
break;
}
return message;
} catch (e) {
return 'Couldn\'t sign up';
}
}
}
Sign Up Screen
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_login_screen/constants.dart';
import 'package:flutter_login_screen/main.dart';
import 'package:flutter_login_screen/model/user.dart';
import 'package:flutter_login_screen/services/authenticate.dart';
import 'package:flutter_login_screen/services/helper.dart';
import 'package:flutter_login_screen/ui/home/homeScreen.dart';
import 'package:image_picker/image_picker.dart';
File? _image;
class SignUpScreen extends StatefulWidget {
#override
State createState() => _SignUpState();
}
class _SignUpState extends State<SignUpScreen> {
final ImagePicker _imagePicker = ImagePicker();
TextEditingController _passwordController = new TextEditingController();
GlobalKey<FormState> _key = new GlobalKey();
AutovalidateMode _validate = AutovalidateMode.disabled;
String? name, email, password, confirmPassword;
#override
Widget build(BuildContext context) {
if (Platform.isAndroid) {
retrieveLostData();
}
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.black),
),
body: SingleChildScrollView(
child: new Container(
margin: new EdgeInsets.only(left: 16.0, right: 16, bottom: 16),
child: new Form(
key: _key,
autovalidateMode: _validate,
child: formUI(),
),
),
),
);
}
Future<void> retrieveLostData() async {
final LostData? response = await _imagePicker.getLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
_image = File(response.file!.path);
});
}
}
_onCameraClick() {
final action = CupertinoActionSheet(
message: Text(
"Add profile picture",
style: TextStyle(fontSize: 15.0),
),
actions: <Widget>[
CupertinoActionSheetAction(
child: Text("Choose from gallery"),
isDefaultAction: false,
onPressed: () async {
Navigator.pop(context);
PickedFile? image =
await _imagePicker.getImage(source: ImageSource.gallery);
if (image != null)
setState(() {
_image = File(image.path);
});
},
),
CupertinoActionSheetAction(
child: Text("Take a picture"),
isDestructiveAction: false,
onPressed: () async {
Navigator.pop(context);
PickedFile? image =
await _imagePicker.getImage(source: ImageSource.camera);
if (image != null)
setState(() {
_image = File(image.path);
});
},
)
],
cancelButton: CupertinoActionSheetAction(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
);
showCupertinoModalPopup(context: context, builder: (context) => action);
}
Widget formUI() {
return new Column(
children: <Widget>[
new Align(
alignment: Alignment.topLeft,
child: Text(
'Create new account',
style: TextStyle(
color: Color(COLOR_PRIMARY),
fontWeight: FontWeight.bold,
fontSize: 25.0),
)),
Padding(
padding:
const EdgeInsets.only(left: 8.0, top: 32, right: 8, bottom: 8),
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
CircleAvatar(
radius: 65,
backgroundColor: Colors.grey.shade400,
child: ClipOval(
child: SizedBox(
width: 170,
height: 170,
child: _image == null
? Image.asset(
'assets/images/placeholder.jpg',
fit: BoxFit.cover,
)
: Image.file(
_image!,
fit: BoxFit.cover,
),
),
),
),
Positioned(
left: 80,
right: 0,
child: FloatingActionButton(
backgroundColor: Color(COLOR_PRIMARY),
child: Icon(Icons.camera_alt),
mini: true,
onPressed: _onCameraClick),
)
],
),
),
ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Padding(
padding:
const EdgeInsets.only(top: 16.0, right: 8.0, left: 8.0),
child: TextFormField(
validator: validateName,
onSaved: (val) => name = val,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'Name',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Color(COLOR_PRIMARY), width: 2.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
))))),
ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Padding(
padding:
const EdgeInsets.only(top: 16.0, right: 8.0, left: 8.0),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
validator: validateEmail,
onSaved: (val) => email = val,
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'Email Address',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Color(COLOR_PRIMARY), width: 2.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
))))),
ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Padding(
padding: const EdgeInsets.only(top: 16.0, right: 8.0, left: 8.0),
child: TextFormField(
obscureText: true,
textInputAction: TextInputAction.next,
controller: _passwordController,
validator: validatePassword,
onSaved: (val) => password = val,
style: TextStyle(height: 0.8, fontSize: 18.0),
cursorColor: Color(COLOR_PRIMARY),
decoration: InputDecoration(
contentPadding:
new EdgeInsets.symmetric(vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'Password',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Color(COLOR_PRIMARY), width: 2.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
))),
)),
ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Padding(
padding: const EdgeInsets.only(top: 16.0, right: 8.0, left: 8.0),
child: TextFormField(
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) => _signUp(),
obscureText: true,
validator: (val) =>
validateConfirmPassword(_passwordController.text, val),
onSaved: (val) => confirmPassword = val,
style: TextStyle(height: 0.8, fontSize: 18.0),
cursorColor: Color(COLOR_PRIMARY),
decoration: InputDecoration(
contentPadding:
new EdgeInsets.symmetric(vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'Confirm Password',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Color(COLOR_PRIMARY), width: 2.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
))),
),
),
Padding(
padding: const EdgeInsets.only(right: 40.0, left: 40.0, top: 40.0),
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: double.infinity),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(COLOR_PRIMARY),
padding: EdgeInsets.only(top: 12, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
side: BorderSide(
color: Color(COLOR_PRIMARY),
),
),
),
child: Text(
'Sign Up',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
onPressed: _signUp,
),
),
),
],
);
}
_signUp() async {
if (_key.currentState?.validate() ?? false) {
_key.currentState!.save();
await _signUpWithEmailAndPassword();
} else {
setState(() {
_validate = AutovalidateMode.onUserInteraction;
});
}
}
_signUpWithEmailAndPassword() async {
await showProgress(context, 'Creating new account, Please wait...', false);
dynamic result = await FireStoreUtils.firebaseSignUpWithEmailAndPassword(
email!.trim(),
password!.trim(),
_image,
name!.trim(),
);
await hideProgress();
if (result != null && result is User) {
MyAppState.currentUser = result;
pushAndRemoveUntil(context, HomeScreen(user: result), false);
} else if (result != null && result is String) {
showAlertDialog(context, 'Failed', result);
} else {
showAlertDialog(context, 'Failed', 'Couldn\'t sign up');
}
}
#override
void dispose() {
_passwordController.dispose();
_image = null;
super.dispose();
}
}
Login Screen
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_login_screen/constants.dart';
import 'package:flutter_login_screen/main.dart';
import 'package:flutter_login_screen/model/user.dart';
import 'package:flutter_login_screen/services/authenticate.dart';
import 'package:flutter_login_screen/services/helper.dart';
import 'package:flutter_login_screen/ui/home/homeScreen.dart';
class LoginScreen extends StatefulWidget {
#override
State createState() {
return _LoginScreen();
}
}
class _LoginScreen extends State<LoginScreen> {
GlobalKey<FormState> _key = new GlobalKey();
AutovalidateMode _validate = AutovalidateMode.disabled;
String? email, password;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: IconThemeData(color: Colors.black),
elevation: 0.0,
),
body: Form(
key: _key,
autovalidateMode: _validate,
child: ListView(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(top: 32.0, right: 16.0, left: 16.0),
child: Text(
'Sign In',
style: TextStyle(
color: Color(COLOR_PRIMARY),
fontSize: 25.0,
fontWeight: FontWeight.bold),
),
),
ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Padding(
padding:
const EdgeInsets.only(top: 32.0, right: 24.0, left: 24.0),
child: TextFormField(
textAlignVertical: TextAlignVertical.center,
textInputAction: TextInputAction.next,
validator: validateEmail,
onSaved: (val) => email = val,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
style: TextStyle(fontSize: 18.0),
keyboardType: TextInputType.emailAddress,
cursorColor: Color(COLOR_PRIMARY),
decoration: InputDecoration(
contentPadding:
new EdgeInsets.only(left: 16, right: 16),
fillColor: Colors.white,
hintText: 'E-mail Address',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Color(COLOR_PRIMARY), width: 2.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
))),
),
),
ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Padding(
padding:
const EdgeInsets.only(top: 32.0, right: 24.0, left: 24.0),
child: TextFormField(
textAlignVertical: TextAlignVertical.center,
validator: validatePassword,
onSaved: (val) => password = val,
onFieldSubmitted: (password) async {
await login();
},
obscureText: true,
textInputAction: TextInputAction.done,
style: TextStyle(fontSize: 18.0),
cursorColor: Color(COLOR_PRIMARY),
decoration: InputDecoration(
contentPadding:
new EdgeInsets.only(left: 16, right: 16),
fillColor: Colors.white,
hintText: 'Password',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Color(COLOR_PRIMARY), width: 2.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
))),
),
),
Padding(
padding: const EdgeInsets.only(right: 40.0, left: 40.0, top: 40),
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: double.infinity),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(COLOR_PRIMARY),
padding: EdgeInsets.only(top: 12, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
side: BorderSide(color: Color(COLOR_PRIMARY))),
),
child: Text(
'Log In',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
onPressed: () => login(),
),
),
),
Padding(
padding: const EdgeInsets.all(32.0),
child: Center(
child: Text(
'OR',
style: TextStyle(color: Colors.black),
),
),
),
Padding(
padding:
const EdgeInsets.only(right: 40.0, left: 40.0, bottom: 20),
child: ConstrainedBox(
constraints: const BoxConstraints(minWidth: double.infinity),
child: ElevatedButton.icon(
label: Text(
'Facebook Login',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
icon: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Image.asset(
'assets/images/facebook_logo.png',
color: Colors.white,
height: 30,
width: 30,
),
),
style: ElevatedButton.styleFrom(
primary: Color(FACEBOOK_BUTTON_COLOR),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
side: BorderSide(
color: Color(FACEBOOK_BUTTON_COLOR),
),
),
),
onPressed: () async => loginWithFacebook(),
),
),
),
],
),
),
);
}
login() async {
if (_key.currentState?.validate() ?? false) {
_key.currentState!.save();
await _loginWithEmailAndPassword();
} else {
setState(() {
_validate = AutovalidateMode.onUserInteraction;
});
}
}
_loginWithEmailAndPassword() async {
await showProgress(context, 'Logging in, please wait...', false);
dynamic result = await FireStoreUtils.loginWithEmailAndPassword(
email!.trim(), password!.trim());
await hideProgress();
if (result != null && result is User) {
MyAppState.currentUser = result;
pushAndRemoveUntil(context, HomeScreen(user: result), false);
} else if (result != null && result is String) {
showAlertDialog(context, 'Couldn\'t Authenticate', result);
} else {
showAlertDialog(
context, 'Couldn\'t Authenticate', 'Login failed, Please try again.');
}
}
loginWithFacebook() async {
try {
await showProgress(context, 'Logging in, Please wait...', false);
dynamic result = await FireStoreUtils.loginWithFacebook();
await hideProgress();
if (result != null && result is User) {
MyAppState.currentUser = result;
pushAndRemoveUntil(context, HomeScreen(user: result), false);
} else if (result != null && result is String) {
showAlertDialog(context, 'Error', result);
} else {
showAlertDialog(context, 'Error', 'Couldn\'t login with facebook.');
}
} catch (e, s) {
await hideProgress();
print('_LoginScreen.loginWithFacebook $e $s');
showAlertDialog(context, 'Error', 'Couldn\'t login with facebook.');
}
}
}
How can I register with a phone number and stay logged in until I log out. I'm using flutter and I already can register a user with a phone number but when the app is re-opened it starts at the login page.
The idea is to stay logged in after sign-up and even after app closed. and I also can't make circular Indicator to show that the app is loading (I would love it if you showed me how to do this as well)
Here is my code.
import 'package:country_code_picker/country_code_picker.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'BottomBarPages/home.dart';
class SignIn extends StatefulWidget {
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
TextEditingController phoneController = new TextEditingController();
String phoneNumber = "";
bool shower = false;
String smsCode;
String verificationCode;
void _onCountryChange(CountryCode countryCode) {
this.phoneNumber = countryCode.toString();
print("New Country selected: " + countryCode.toString());
}
void check() {
final myPhone = this.phoneNumber + phoneController.text;
print("Full Text: " + myPhone);
}
Future<void> man() async{
}
Future<void> submit() async {
final myPhone = this.phoneNumber + phoneController.text;
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential credential) {
setState(() {
print(credential);
});
};
final PhoneVerificationFailed verificationFailed =
(AuthException exception) {};
final PhoneCodeSent phoneCodeSent = (String verId, [int forceCodeResend]) {
this.verificationCode = verId;
smsCodeDialog(context).then((value) => print("signed"));
};
final PhoneCodeAutoRetrievalTimeout autoRetrievalTimeout = (String verId) {
this.verificationCode = verId;
};
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: myPhone,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: phoneCodeSent,
codeAutoRetrievalTimeout: autoRetrievalTimeout);
}
Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
'Enter Code',
style: TextStyle(color: Colors.lightGreen, fontSize: 24),
),
content: TextField(
keyboardType: TextInputType.number,
onChanged: (Value) {
smsCode = Value;
},
),
contentPadding: EdgeInsets.all(10),
actions: [
FlatButton(
onPressed: () {
FirebaseAuth.instance.currentUser().then((user) {
if (user != null) {
Navigator.of(context).pop();
Navigator.push(context,
MaterialPageRoute(builder: (context) => Home()));
} else {
Navigator.of(context).pop();
signIn();
}
});
},
child: Text(
'Verify',
style: TextStyle(fontSize: 20, color: Colors.lightGreen),
))
],
);
});
// CircularProgressIndicator(
// valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightGreen),
// value: 0.25,
// );
}
signIn() {
AuthCredential phoneAuthCredential = PhoneAuthProvider.getCredential(
verificationId: verificationCode, smsCode: smsCode);
FirebaseAuth.instance
.signInWithCredential(phoneAuthCredential)
.then((user) => Navigator.push(
context, MaterialPageRoute(builder: (context) => Home())))
.catchError((e) => print(e));
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
body: Column(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0.1, 0.3, 1.0],
colors: [
Colors.lightGreen[300],
Colors.white,
Colors.lightGreen[50]
],
),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 150,
child: Image.asset('images/phone.png'),
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(color: Colors.lightGreen)),
width: double.infinity,
height: 40,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CountryCodePicker(
dialogTextStyle: TextStyle(fontSize: 20),
onChanged: _onCountryChange,
initialSelection: 'US',
favorite: ['+251', 'ET'],
),
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SizedBox(
width: 150,
child: TextFormField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
),
],
),
),
),
),
SizedBox(
height: 20,
),
MaterialButton(
onPressed: submit,
minWidth: MediaQuery.of(context).size.width - 80,
height: 45,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
color: Colors.lightGreen,
splashColor: Colors.green,
child: Text(
"Confirm",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
Padding(
padding:
EdgeInsets.symmetric(vertical: 14, horizontal: 64),
child: Text(
"you'll receive a 6 digit code click Confirm to verify",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Colors.lightGreen,
),
),
),
],
),
),
),
),
],
),
),
);
}
}
Please help me.
When your application opens, check if the user is already logged in or not using:
User user = FirebaseAuth.instance.currentUser;
if user is not null then you should navigate the app to the home or some other screen. Try this code:
#override
void initState() {
super.initState();
getUser();
}
getUser() {
User firebaseUser = FirebaseAuth.instance.currentUser;
if (firebaseUser != null)
WidgetsBinding.instance.addPostFrameCallback((_) =>
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage())));
}
when i try to press on the send button to do the http request[which is done successflly] i got the below error, how can i solve it?!!
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: setState() called after dispose(): _ForgetPasswordDialogState#95548(lifecycle state: defunct, not mounted
import 'dart:io';
import 'package:Zabatnee/common_app/provider/user_details_provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ForgetPasswordDialog extends StatefulWidget {
static const routeName = '/customeDialog';
final String title,description;
ForgetPasswordDialog({
this.title,
this.description,});
#override
_ForgetPasswordDialogState createState() => _ForgetPasswordDialogState();
}
class _ForgetPasswordDialogState extends State<ForgetPasswordDialog> {
final emailController = TextEditingController();
var _isLoading = false;
_showDialog(String title, String message) {
showDialog(
barrierDismissible: false,
context: context,
builder: (ctx) => WillPopScope(
onWillPop: () async => false,
child: new AlertDialog(
elevation: 15,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8))),
title: Text(
title,
style: TextStyle(color: Colors.white),
),
content: Text(
message,
style: TextStyle(color: Colors.white),
),
backgroundColor: Theme.of(context).primaryColor,
actions: <Widget>[
FlatButton(
child: Text(
'OK',
style: TextStyle(color: Theme.of(context).accentColor),
),
onPressed: () {
Navigator.of(context).pop();
setState(
() {
_isLoading = false;
},
);
},
)
],
),
),
);
}
Future<void> _forgetPassword (String email) async {
try{
setState(() {
_isLoading = true;
});
await Provider.of<UserDetailsProvider>(context, listen: false).forgetPassword(email);
print('code are sent via email');
} on HttpException catch (error) {
_showDialog('Authentication Failed', error.message);
} on SocketException catch (_) {
_showDialog('An error occured',
'please check your internet connection and try again later');
} catch (error) {
_showDialog('Authentication Failed',
'Something went wrong, please try again later');
}
setState(() {
_isLoading = false;
});
}
#override
void dispose() {
emailController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16)
),
elevation: 8,
backgroundColor: Theme.of(context).accentColor,
child: dialogContent(context),
);
}
dialogContent(BuildContext context){
return Container(
padding: EdgeInsets.only(
top: 50,
right: 16,
left: 16,
bottom: 16,
),
margin: EdgeInsets.all(8),
width: double.infinity,
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(17),
boxShadow: [
BoxShadow(
color: Colors.black87,
blurRadius: 10.0,
offset: Offset(0.0,10.0),
)
]
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
widget.title,
style: TextStyle(
fontSize: 24,
),
),
SizedBox(
height: 20,
),
Text(widget.description, style: TextStyle(fontSize: 16),
),
SizedBox(
height: 20,
),
TextField(
controller: emailController,
style: TextStyle(color: Colors.white),
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(color:Theme.of(context).primaryColor)
),
fillColor: Colors.black87,
hintStyle: TextStyle(color:Colors.grey),
hintText: 'please enter your email',
labelText: 'Email',
labelStyle: TextStyle(color:Colors.white)
),
),
SizedBox(
height: 20,
),
Container(
width: double.infinity,
child: RaisedButton(
child: Text('Send'),
onPressed: (){
_isLoading
? CircularProgressIndicator()
: print(emailController.text);
_forgetPassword(emailController.text);
Navigator.of(context).pop();
}
),
),
Container(
width: double.infinity,
child: RaisedButton(
child: Text('Cancel'),
onPressed: (){
Navigator.of(context).pop();
}
),
),
],
),
);
}
}
Replace your
setState((){});
with
if (mounted) setState(() {});.
The mounted checks Whether the [State] object is currently in a tree. That way, you would be able to avoid the error.
thanks to Peter Haddad
We have built code to retrieve data from my cloud Store collection called "user"
at the moment as you can see into the widget we will show the use with a specific email "info#text.it"
class MainWelcome extends StatefulWidget {
#override
_MainWelcomeState createState() => _MainWelcomeState();
}
class _MainWelcomeState extends State<MainWelcome> {
final databaseReference = Firestore.instance;
Future<QuerySnapshot> getData() async {
return await Firestore.instance.collection("user").where("email", isEqualTo: "info#text.it").getDocuments();
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getData(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) {
return Column(
children: [
Text(snapshot.data.documents[index].data["name"]),
Text(snapshot.data.documents[index].data["food"]),
Text(snapshot.data.documents[index].data["email"]),
],
);
});
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
}
return CircularProgressIndicator();
},
);
}
}
where isEqualTo "info#text.it" I need to replace it with a variable to get into the widget each of the user subscribed into my form.
this is the form:
void createRecord() async {
await databaseReference.collection("user")
.add({
'name': '$name',
'email': '$email',
'password': '$password',
'food': '$food',
'image': '$image',
}).then((value){
print(value.documentID);
});
Widget mailField() {
return Center(
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: Container(
width: 360,
child: TextField(
style: TextStyle(color: Colors.white),
keyboardType: TextInputType.emailAddress,
onChanged: (value) {
email = value;
},
decoration: InputDecoration(
icon: new Icon(
Icons.mail,
color: Colors.white,
),
hintText: 'La tua email',
focusColor: Colors.white,
hintStyle: TextStyle(color: Colors.white),
prefixStyle: TextStyle(color: Colors.white),
labelText: 'La tua email',
labelStyle: TextStyle(
color: Colors.white,
),
contentPadding:
EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
),
),
),
),
);
}
Widget submitButton() {
return Container(
child: SizedBox(
width: 220,
height: 40,
child: RaisedButton(
elevation: 5,
onPressed: () async {
setState(() {
showProgress = true;
createRecord();
});
try {
final newuser = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
if (newuser != null) {
Navigator.push(context, PageTransition(
type: PageTransitionType.fade,
child: WelcomeScreen(),
));
setState(() {
showProgress = false;
});
}
} catch (e) {
return Container(
child: Text('Error'),
);
}
},
child: Text(
'Registrati',
style: TextStyle(color: Colors.black),
),
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Colors.black12, width: 1)),
),
),
);
}
Since you are using Firebase Authentication, then get the email from there:
Future<QuerySnapshot> getData() async {
var firebaseUser = await FirebaseAuth.instance.currentUser();
return await Firestore.instance.collection("user").where("email", isEqualTo: firebaseUser.email).getDocuments();
}