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
Related
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.');
}
}
}
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()
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.
hey guys i am trying to use login system in my app but progress bar always stays and says logging in but never logging in i can register and also i can see user details on firestore bur end of the console i got that error "PlatformException(error, Given String is empty or null, null) error"
is there anyway to fix that error if you have any suggestions let me know thanks
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:resat/src/pages/LoginPages/model/User.dart';
import 'package:resat/src/pages/LoginPages/ui/home/HomeScreen.dart';
import 'package:resat/src/pages/LoginPages/ui/services/Authenticate.dart';
import 'package:resat/src/pages/LoginPages/ui/utils/helper.dart';
import 'package:http/http.dart' as http;
import '../../constants.dart' as Constants;
import '../../main.dart';
final _fireStoreUtils = FireStoreUtils();
class LoginScreen extends StatefulWidget {
#override
State createState() {
return _LoginScreen();
}
}
class _LoginScreen extends State<LoginScreen> {
TextEditingController _emailController = new TextEditingController();
TextEditingController _passwordController = new TextEditingController();
GlobalKey<FormState> _key = new GlobalKey();
bool _validate = false;
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,
autovalidate: _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(Constants.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: (String val) {
email = val;
},
onFieldSubmitted: (_) =>
FocusScope.of(context).nextFocus(),
controller: _emailController,
style: TextStyle(fontSize: 18.0),
keyboardType: TextInputType.emailAddress,
cursorColor: Color(Constants.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(Constants.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: (String val) {
email = val;
},
onFieldSubmitted: (password) async {
await onClick(_emailController.text, password);
},
textInputAction: TextInputAction.done,
style: TextStyle(fontSize: 18.0),
cursorColor: Color(Constants.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(Constants.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: RaisedButton(
color: Color(Constants.COLOR_PRIMARY),
child: Text(
'Log In',
style:
TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
textColor: Colors.white,
splashColor: Color(Constants.COLOR_PRIMARY),
onPressed: () async {
await onClick(
_emailController.text, _passwordController.text);
},
padding: EdgeInsets.only(top: 12, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
side:
BorderSide(color: Color(Constants.COLOR_PRIMARY))),
),
),
),
Padding(
padding: const EdgeInsets.all(32.0),
child: Center(
child: Text(
'OR',
style: TextStyle(color: Colors.black),
),
),
),
],
),
),
);
}
onClick(String email, String password) async {
if (_key.currentState.validate()) {
_key.currentState.save();
showProgress(context, 'Logging in, please wait...', false);
User user =
await loginWithUserNameAndPassword(email, password.trim());
if (user != null)
pushAndRemoveUntil(context, HomeScreen(user: user), false);
} else {
setState(() {
_validate = true;
});
}
}
Future<User> loginWithUserNameAndPassword(String email,
String password) async {
try {
AuthResult result = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
DocumentSnapshot documentSnapshot = await FireStoreUtils.firestore
.collection(Constants.USERS)
.document(result.user.uid)
.get();
User user;
if (documentSnapshot != null && documentSnapshot.exists) {
user = User.fromJson(documentSnapshot.data);
user.active = true;
await _fireStoreUtils.updateCurrentUser(user, context);
hideProgress();
MyAppState.currentUser = user;
}
return user;
} catch (exception) {
hideProgress();
switch ((exception as PlatformException).code) {
case 'ERROR_INVALID_EMAIL':
showAlertDialog(
context, 'Couldn\'t Authinticate', 'email address is malformed');
break;
case 'ERROR_WRONG_PASSWORD':
showAlertDialog(context, 'Couldn\'t Authinticate', 'wrong password');
break;
case 'ERROR_USER_NOT_FOUND':
showAlertDialog(context, 'Couldn\'t Authinticate',
'no user corresponding to the given email address');
break;
case 'ERROR_USER_DISABLED':
showAlertDialog(
context, 'Couldn\'t Authinticate', 'user has been disabled');
break;
case 'ERROR_TOO_MANY_REQUESTS':
showAlertDialog(context, 'Couldn\'t Authinticate',
'too many attempts to sign in as this user');
break;
case 'ERROR_OPERATION_NOT_ALLOWED':
showAlertDialog(context, 'Couldn\'t Authinticate',
'Email & Password accounts are not enabled');
break;
}
print(exception.toString());
return null;
}
}
#override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
}
You need to bind the _passwordController to the field:
child: TextFormField(
textAlignVertical: TextAlignVertical.center,
validator: validatePassword,
onSaved: (String val) {
email = val;
},
onFieldSubmitted: (password) async {
await onClick(_emailController.text, _passwordController.text);
},
controller : _passwordController,
textInputAction: TextInputAction.done,
style: TextStyle(fontSize: 18.0),