Adding new roles in the same application - flutter

Im trying to add a new sign in role for Rider to sign in to see the orders from customers in the same app but im not sure if im able to add it into my existing code for currently just user to register, sign in and sign up for a new role which is the rider. Would appreciate some advice or suggestion. thank you.
my user model:
class UserModel {
String? uid;
String? email;
String? firstName;
String? secondName;
UserModel({this.uid, this.email, this.firstName, this.secondName});
// receiving data from server
factory UserModel.fromMap(map) {
return UserModel(
uid: map['uid'],
email: map['email'],
firstName: map['firstName'],
secondName: map['secondName'],
);
}
// sending data to our server
Map<String, dynamic> toMap() {
return {
'uid': uid,
'email': email,
'firstName': firstName,
'secondName': secondName,
};
}
}
my sign up:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
//import 'package:grocery_shopping/pages/home/homepage.dart';
import 'package:grocery_shopping/signin.dart';
import 'package:grocery_shopping/user_model.dart';
class SignUp extends StatefulWidget {
const SignUp({Key? key}) : super(key: key);
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final _auth = FirebaseAuth.instance;
// string for displaying the error Message
String? errorMessage;
// our form key
final _formKey = GlobalKey<FormState>();
// editing Controller
final firstNameEditingController = new TextEditingController();
final secondNameEditingController = new TextEditingController();
final emailEditingController = new TextEditingController();
final passwordEditingController = new TextEditingController();
final confirmPasswordEditingController = new TextEditingController();
#override
Widget build(BuildContext context) {
//first name field
final firstNameField = TextFormField(
autofocus: false,
controller: firstNameEditingController,
keyboardType: TextInputType.name,
validator: (value) {
RegExp regex = new RegExp(r'^.{3,}$');
if (value!.isEmpty) {
return ("First Name cannot be Empty");
}
if (!regex.hasMatch(value)) {
return ("Enter Valid name(Min. 3 Character)");
}
return null;
},
onSaved: (value) {
firstNameEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.account_circle),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "First Name",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
));
//second name field
final secondNameField = TextFormField(
autofocus: false,
controller: secondNameEditingController,
keyboardType: TextInputType.name,
validator: (value) {
if (value!.isEmpty) {
return ("Second Name cannot be Empty");
}
return null;
},
onSaved: (value) {
secondNameEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.account_circle),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Second Name",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
));
//email field
final emailField = TextFormField(
autofocus: false,
controller: emailEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Please Enter Your Email");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please Enter a valid email");
}
return null;
},
onSaved: (value) {
firstNameEditingController.text = value!;
},
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: passwordEditingController,
obscureText: true,
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("Password is required for login");
}
if (!regex.hasMatch(value)) {
return ("Enter Valid Password(Min. 6 Character)");
}
},
onSaved: (value) {
firstNameEditingController.text = value!;
},
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 field
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordEditingController,
obscureText: true,
validator: (value) {
if (confirmPasswordEditingController.text !=
passwordEditingController.text) {
return "Password don't match";
}
return null;
},
onSaved: (value) {
confirmPasswordEditingController.text = value!;
},
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),
),
));
//signup button
final signUpButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.lightBlueAccent,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery
.of(context)
.size
.width,
onPressed: () {
signUp(emailEditingController.text, passwordEditingController.text);
},
child: Text(
"SignUp",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),
)),
);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.blue),
onPressed: () {
// passing this to our root
Navigator.of(context).pop();
},
),
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Colors.white,
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: Image.asset(
"assets/grocery shopping logo.png",
fit: BoxFit.contain,
)),
SizedBox(height: 45),
firstNameField,
SizedBox(height: 20),
secondNameField,
SizedBox(height: 20),
emailField,
SizedBox(height: 20),
passwordField,
SizedBox(height: 20),
confirmPasswordField,
SizedBox(height: 20),
signUpButton,
SizedBox(height: 15),
],
),
),
),
),
),
),
);
}
void signUp(String email, String password) async {
if (_formKey.currentState!.validate()) {
try {
await _auth
.createUserWithEmailAndPassword(email: email, password: password)
.then((value) => {postDetailsToFirestore()})
.catchError((e) {
Fluttertoast.showToast(msg: "SignUp Successful");
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => SignIn()));
});
} on FirebaseAuthException catch (error) {
switch (error.code) {
case "invalid-email":
errorMessage = "Your email address appears to be malformed.";
break;
case "wrong-password":
errorMessage = "Your password is wrong.";
break;
case "user-not-found":
errorMessage = "User with this email doesn't exist.";
break;
case "user-disabled":
errorMessage = "User with this email has been disabled.";
break;
case "too-many-requests":
errorMessage = "Too many requests";
break;
case "operation-not-allowed":
errorMessage = "Signing in with Email and Password is not enabled.";
break;
default:
errorMessage = "An undefined Error happened.";
}
Fluttertoast.showToast(msg: errorMessage!);
print(error.code);
}
}
}
postDetailsToFirestore() async {
// calling our firestore
// calling our user model
// sedning these values
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
User? user = _auth.currentUser;
UserModel userModel = UserModel();
// writing all the values
userModel.email = user!.email;
userModel.uid = user.uid;
userModel.firstName = firstNameEditingController.text;
userModel.secondName = secondNameEditingController.text;
await firebaseFirestore
.collection("users")
.doc(user.uid)
.set(userModel.toMap());
Fluttertoast.showToast(msg: "Account created successfully :) ");
Navigator.pushAndRemoveUntil(
(context),
MaterialPageRoute(builder: (context) => SignIn()),
(route) => false);
}
}
my sign in:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:grocery_shopping/signup.dart';
import 'package:grocery_shopping/pages/home/homepage.dart';
class SignIn extends StatefulWidget {
const SignIn({Key? key}) : super(key: key);
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
// form key
final _formKey = GlobalKey<FormState>();
// editing controller
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
// firebase
final _auth = FirebaseAuth.instance;
// string for displaying the error Message
String? errorMessage;
#override
Widget build(BuildContext context) {
//email field
final emailField = TextFormField(
autofocus: false,
controller: emailController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Please Enter Your Email");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please Enter a valid email");
}
return null;
},
onSaved: (value) {
emailController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.mail),
contentPadding: const 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) {
RegExp regex = RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("Password is required for login");
}
if (!regex.hasMatch(value)) {
return ("Enter Valid Password(Min. 6 Character)");
}
},
onSaved: (value) {
passwordController.text = value!;
},
textInputAction: TextInputAction.done,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.vpn_key),
contentPadding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
));
final loginButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.lightBlueAccent,
child: MaterialButton(
padding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signIn(emailController.text, passwordController.text);
},
child: const Text(
"Sign In",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold),
)),
);
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: SingleChildScrollView(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200,
child: Image.asset(
"assets/grocery shopping logo.png",
fit: BoxFit.contain,
)),
const SizedBox(height: 45),
emailField,
const SizedBox(height: 25),
passwordField,
const SizedBox(height: 35),
loginButton,
const SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("Don't have an account? "),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const SignUp()));
},
child: const Text(
"SignUp",
style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 15),
),
)
])
],
),
),
),
),
),
),
);
}
// login function
void signIn(String email, String password) async {
if (_formKey.currentState!.validate()) {
try {
await _auth
.signInWithEmailAndPassword(email: email, password: password)
.then((uid) => {
Fluttertoast.showToast(msg: "Login Successful"),
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const CatalogScreen())),
});
} on FirebaseAuthException catch (error) {
switch (error.code) {
case "invalid-email":
errorMessage = "Your email address appears to be malformed.";
break;
case "wrong-password":
errorMessage = "Your password is wrong.";
break;
case "user-not-found":
errorMessage = "User with this email doesn't exist.";
break;
case "user-disabled":
errorMessage = "User with this email has been disabled.";
break;
case "too-many-requests":
errorMessage = "Too many requests";
break;
case "operation-not-allowed":
errorMessage = "Signing in with Email and Password is not enabled.";
break;
default:
errorMessage = "An undefined Error happened.";
}
Fluttertoast.showToast(msg: errorMessage!);
print(error.code);
}
}
}
}

Related

Conditional statement for DropdownButtonFormFields in registeration form

Still a newbie with flutter and was wondering if someone could help me with a problem I'm having. I am trying to create a registeration form with email, password, password confirmation, a county and a zip code. (County and zip code forms are the drop down button form fields) I have successfully coded all else except for the zip code drop down. I would need it to be conditional on the county selection. (In a way that if I select a specific county in cali, it would only display that selected county's zip codes and nothing else). Also if someone would know a quick fix to make the dropdown button form fields empty unless clicked on. My current adaptation on it isn't very functional, since you can just leave the option unanswered, when it's supposed to be mandatory. Thank you in advance :)
Existing code below
(I only have the string for one county zip codes) (Also deleted the irrelevant firebase related code for this post)
class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);
#override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
// dropdown area
_MyFormStateArea(){
selectedArea = dropdownListArea[0];
}
var selectedArea = '';
final dropdownListArea = <String>['', 'LA', 'San Francisco'...'Santa Barbara'];
// dropdown zipcode
_MyFormStateZip(){
selectedZip = dropdownListZip[0];
}
var selectedZip = '';
final dropdownListZip = <String>['', '90001', '90002', '90003',..., '91609'];
// editing Controller
final emailEditingController = new TextEditingController();
final passwordEditingController = new TextEditingController();
final confirmPasswordEditingController = new TextEditingController();
#override
Widget build(BuildContext context) {
// email field
final emailField = TextFormField(
autofocus: false,
controller: emailEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value!.isEmpty) {
return ("Please enter email.");
}
// reg expression for email validation
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return ("Please enter a working email.");
}
return null;
},
onSaved: (value) {
emailEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail_outline_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// password field
final passwordField = TextFormField(
autofocus: false,
controller: passwordEditingController,
obscureText: true,
validator: (value) {
RegExp regex = new RegExp(r'^.{6,}$');
if (value!.isEmpty) {
return ("A password required.");
}
if(!regex.hasMatch(value)) {
return ("Please enter other password (Min. 6 characters)");
}
},
onSaved: (value) {
passwordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
));
// confirm password field
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordEditingController,
obscureText: true,
validator: (value)
{
if(confirmPasswordEditingController.text != passwordEditingController.text)
{
return "Passwords don't match";
}
return null;
},
onSaved: (value) {
confirmPasswordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password again",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
);
// area dropdown
final areaField = DropdownButtonFormField(
value: selectedArea,
items: dropdownListArea.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: dropdownListZip.map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// sign up button
final signUpButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.white,
child: MaterialButton(
padding: EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signUp(emailEditingController.text, passwordEditingController.text);
},
child: Text("Sign Up", textAlign: TextAlign.center,
style: TextStyle(fontSize: 20,
color: Colors.lightBlue[900],
fontWeight: FontWeight.bold)
),
),
);
return Scaffold(
backgroundColor: Color(0xFFAED8E6),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => FrontPage()));
},
icon: Icon(Icons.arrow_back),
color: Colors.lightBlue[900],
),
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Color(0xFFAED8E6),
child: Padding(
padding: const EdgeInsets.fromLTRB(36, 20, 36, 30),
child: Form(
key: _formKey,
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 170,
child: Image.asset("assets/AR_logoBold.png",
fit: BoxFit.contain
)),
SizedBox(height: 40,),
emailField,
SizedBox(height: 25,),
passwordField,
SizedBox(height: 25,),
confirmPasswordField,
SizedBox(height: 25,),
areaField,
SizedBox(height: 25,),
zipCodeField,
SizedBox(height: 35,),
signUpButton,
SizedBox(height: 15,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("You already own an account? "),
GestureDetector(onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Text("Login",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.lightBlue[900])
),)
],
)
],
)),
),
),
),
),
);
}
}
First you should initalize the selectedArea and selectedZip with the first Entry of your List: = dropdownListZip.first and the first entry should not be an empty String
To get only zips that belong to the choosen area you need to know them. At the moment you have two independent lists.
Better you use a map like:
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
Than you can only display zips that belong to the area quite easy.
Take a look at: Flutter Documentation for Map
Map<String, List<String>> zipmap = Map('LA': ['9000','9001','9002], 'San Francisco': ['9003', '9004']);
final areaField = DropdownButtonFormField(
value: selectedArea,
items: zipmap.keys.toList().map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedArea = value;
}
});
},
decoration: InputDecoration(
labelText: 'County',
prefixIcon: Icon(Icons.location_city_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);
// zip code field
final zipCodeField = DropdownButtonFormField(
value: selectedZip,
items: zipmap[selectedArea].map((e) =>
DropdownMenuItem(value: e, child: Text(e),)).toList(),
onChanged: (String? value) {
setState(() {
if (value != null) {
selectedZip = value;
}
});
},
decoration: InputDecoration(
labelText: 'Zip Code',
prefixIcon: Icon(Icons.location_on_outlined),
contentPadding: EdgeInsets.fromLTRB(20, 10, 0, 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)),
)
);

Adding data to collection firestore flutter with relevant user

This is just some basic registration ui
I need to send these data when user is registering.
Currently I need to send First Name and Last Name.
Sending data is okay but they don't have a field.
Is there a way to add user id when I click Sign Up button?
So how do I send that data according to relevant user???
And how to retrieve that data with relevant user?
Hope you help me on this
Thank you
class RegisterView extends StatefulWidget {
const RegisterView({Key? key}) : super(key: key);
#override
State<RegisterView> createState() => _RegisterViewState();
}
class _RegisterViewState extends State<RegisterView> {
late final TextEditingController _email;
late final TextEditingController _password;
late final TextEditingController _firstName;
late final TextEditingController _lastName;
final _formKey = GlobalKey<FormState>();
#override
void initState() {
_email = TextEditingController();
_password = TextEditingController();
_firstName = TextEditingController();
_lastName = TextEditingController();
super.initState();
}
#override
void dispose() {
_firstName.dispose();
_lastName.dispose();
_email.dispose();
_password.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromARGB(255, 185, 185, 185),
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 87, 127, 160),
elevation: 0,
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
),
body: ListView(
children: [
Container(
height: 150,
padding: const EdgeInsets.only(top: 40),
decoration: const BoxDecoration(
color: Color.fromARGB(255, 87, 127, 160),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(150),
bottomRight: Radius.circular(150),
),
),
child: const Text(
'Create New Account',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 35,
color: Colors.black,
),
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 40,
vertical: 30,
),
child: Form(
key: _formKey,
child: Column(
children: [
// First name and last name
Row(
children: [
Flexible(
// First Name
child: TextFormField(
decoration: const InputDecoration(
labelText: 'First Name',
),
validator: (val) => val!.isEmpty ? 'requied*' : null,
controller: _firstName,
),
),
const SizedBox(
width: 20.0,
),
Flexible(
// Last Name
child: TextFormField(
decoration: const InputDecoration(
labelText: 'Last Name',
),
validator: (val) => val!.isEmpty ? 'requied*' : null,
controller: _lastName,
),
),
],
),
// Email Address
TextFormField(
decoration: const InputDecoration(
labelText: 'Email address',
),
keyboardType: TextInputType.emailAddress,
controller: _email,
validator: (val) => val!.isEmpty ? 'requied*' : null,
),
// Password
TextFormField(
decoration: const InputDecoration(
labelText: 'Create a Password',
),
controller: _password,
obscureText: true,
enableSuggestions: false,
autocorrect: false,
validator: (val) => (val!.isEmpty && val.length < 5)
? 'Enter a password with more than 6 characters'
: null,
),
const SizedBox(
height: 20,
),
// Sign Up Button
TextButton(
style: TextButton.styleFrom(
backgroundColor: const Color.fromARGB(255, 0, 132, 255),
),
onPressed: () async {
final email = _email.text;
final password = _password.text;
if (_formKey.currentState!.validate()) {
try {
final userCredential =
await AuthService.firebase().register(
email: email,
password: password,
);
Map<String, dynamic> data = {
'first_name': _firstName.text,
'last_name': _lastName.text,
};
await FirebaseFirestore.instance
.collection('user')
.add(data);
devtools.log(userCredential.toString());
await showErrorDialog(
context,
'Registration Successful !\nYou can log in now.',
).then(
(value) {
Navigator.of(context).pushNamedAndRemoveUntil(
loginRoute, (route) => false);
},
);
} on InvalidEmailAuthException {
await showErrorDialog(
context,
'Invalid email',
);
} on WeakPasswordAuthException {
await showErrorDialog(
context,
'Weak password',
);
} on EmailAlreadyUsedAuthException {
await showErrorDialog(
context,
'Email already in use',
);
} on GenericAuthException {
await showErrorDialog(
context,
'Failed to register',
);
}
}
},
child: const Text(
'Sign Up',
style: TextStyle(
color: Colors.white,
),
),
),
],
),
),
),
],
),
);
}
}
Your current code for writing the user data is:
FirebaseFirestore.instance
.collection('user')
.add(data);
This generates a unique ID for the data.
If you want to store the data under the UID of the user, you can do so with:
FirebaseFirestore.instance
.collection('user')
.doc(userCredential.user!.uid)
.set(data);
Also see:
Flutter Firestore add new document with Custom ID

Exception caught by gesture 'then' was called on null

I faced this error when I tried to insert image
"The following NoSuchMethodError was thrown while handling a gesture:
The method 'then' was called on null.
Receiver: null
Tried calling: then(Closure: (dynamic) => Null)"
Below is my code. Hope someone can help me with it. I have no idea how to solve it. Thank you.
// ignore_for_file: import_of_legacy_library_into_null_safe, unrelated_type_equality_checks
import 'dart:io';
import 'package:dparking/model/user_model.dart';
import 'package:dparking/screens/home_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart';
class RegistrationScreen extends StatefulWidget {
const RegistrationScreen({Key? key}) : super(key: key);
#override
State<RegistrationScreen> createState() => _RegistrationScreenState();
}
class _RegistrationScreenState extends State<RegistrationScreen> {
final _auth = FirebaseAuth.instance;
// form key
final _formKey = GlobalKey<FormState>();
// editing Controller
final nameEditingController = TextEditingController();
final emailEditingController = TextEditingController();
final passwordEditingController = TextEditingController();
final confirmPasswordEditingController = TextEditingController();
final phoneNumberEditingController = TextEditingController();
XFile? _logo;
final ImagePicker _picker = ImagePicker();
#override
Widget build(BuildContext context) {
// Name field
final nameField = TextFormField(
autofocus: false,
controller: nameEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value) {
RegExp regex = RegExp(r'^.{3,}$');
if(value!.isEmpty){
return ("Name cannot be Empty");
}
if(!regex.hasMatch(value))
{
return ("Enter Valid Name(Min. 3 Character");
}
return null;
},
onSaved: (value)
{
nameEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.account_circle),
contentPadding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Name",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
// Email field
final emailField = TextFormField(
autofocus: false,
controller: emailEditingController,
keyboardType: TextInputType.emailAddress,
validator: (value)
{
if(value!.isEmpty)
{
return ("Please Enter Your Email");
}
// reg expression for email validation
if(!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]").hasMatch(value))
{
return("Please Enter a valid email");
}
return null;
},
onSaved: (value)
{
emailEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.mail),
contentPadding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Email",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
// Password field
final passwordField = TextFormField(
autofocus: false,
controller: passwordEditingController,
obscureText: true,
validator: (value) {
RegExp regex = RegExp(r'^.{6,}$');
if(value!.isEmpty){
return ("Password is required for login");
}
if(!regex.hasMatch(value))
{
return ("Enter Valid Password(Min. 6 Character");
}
return null;
},
onSaved: (value)
{
passwordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.vpn_key),
contentPadding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
// Confirm Password field
final confirmPasswordField = TextFormField(
autofocus: false,
controller: confirmPasswordEditingController,
obscureText: true,
validator: (value)
{
if(confirmPasswordEditingController.text.length !=
passwordEditingController.text){
return "Password Does Not Match";
}
return null;
},
onSaved: (value)
{
confirmPasswordEditingController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.vpn_key),
contentPadding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Confirm Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
//signup button
final signupButton = Material(
elevation: 5,
borderRadius: BorderRadius.circular(30),
color: Colors.redAccent,
child: MaterialButton(
padding: const EdgeInsets.fromLTRB(20, 15, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
signUp(emailEditingController.text, passwordEditingController.text);
},
child: const Text("SignUp", textAlign: TextAlign.center,
style: TextStyle(fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold,),
),
),
);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.red),
onPressed: (){
Navigator.of(context).pop();
},
),
),
body: Center(
child: SingleChildScrollView(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 200,
width: 300,
child: Image.asset("assets/images/DParking.png",
fit: BoxFit.contain,
color: Colors.black,
),
),
nameField,
const SizedBox(height: 30),
emailField,
const SizedBox(height: 30),
passwordField,
const SizedBox(height: 30),
confirmPasswordField,
const SizedBox(height: 30),
InkWell(
onTap: (){
_pickImage().then((value){ //i think the error is here
setState((){
_logo = value;
});
});
},
child: Card(
elevation: 4,
child: _logo==null ? const SizedBox(
height: 100,
width: 250,
child: Center(
child: Text('Insert Identification Card'),
),
):SizedBox(
height: 100,
width: 250,
child: Image.file(File(_logo!.path),)
),
),
),
const SizedBox(height: 30),
signupButton,
const SizedBox(height: 30),
],
),
),
),
),
),
)
);
}
void signUp(String email, String password) async
{
if (_formKey.currentState!.validate()) {
await _auth
.createUserWithEmailAndPassword(email: email, password: password)
.then((value) => {postDetailsToFirestore()})
.catchError((e) {
Fluttertoast.showToast(msg: e!.message);
});
}
}
postDetailsToFirestore() async {
// call firestore
//call user model
//send value
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
User? user = _auth.currentUser;
UserModel userModel = UserModel();
userModel.email = user!.email;
userModel.uid = user.uid;
userModel.name = nameEditingController.text;
await firebaseFirestore
.collection("users")
.doc(user.uid)
.set(userModel.toMap());
Fluttertoast.showToast(msg: "Account created successfully");
Navigator.pushAndRemoveUntil(
(context),
MaterialPageRoute(builder: (context) => const HomeScreen()),
(route) => false);
}
}
_pickImage() {
}

why is the form not validated? validator flutter form validation

import 'package:flutter/material.dart';
import 'package:sumanthk07/utilities/routes.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _formkey = GlobalKey<FormState>();
// ignore: avoid_types_as_parameter_names, non_constant_identifier_names
moveToHome(BuildContext) async{
Navigator.pushNamed(context, MyRoutes.homeRoute);
}
#override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
child: SingleChildScrollView(
child: Form(
key: _formkey,
child: Column(
children: [
Image.asset("assets/images/login.png", fit: BoxFit.cover),
const SizedBox(
height: 20.0,
),
const Text(
'Welcome',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 20.0,
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 32.0),
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
hintText: "Enter User name", labelText: "Username "),
initialValue: "",
validator: (String? value) {
if (value !=null && value.isEmpty ) {
return "User name cannot be empty";
}
return null;
},
onChanged: (value) {
setState(() {});
},
),
TextFormField(
obscureText: true,
decoration: const InputDecoration(
hintText: "Enter password", labelText: "Password "),
initialValue: "",
validator: (String? value) {
if (value !=null && value.isEmpty ) {
return "Password name cannot be empty";
}
return null;
},
),
const SizedBox(
height: 20.0,
),
InkWell(
onTap: () => moveToHome(context),
child: AnimatedContainer(
duration: const Duration(seconds: 1),
height: 40,
width: 80,
alignment: Alignment.center,
child: const Text("Login",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
)),
decoration: BoxDecoration(
color: Colors.red,
// ignore: unnecessary_const
borderRadius: BorderRadius.circular(20)),
),
)
// ElevatedButton(
// child: const Text("Login"),
// style: TextButton.styleFrom(),
// onPressed: () {
// // ignore: unused_local_variable
// var myRoutes = MyRoutes;
// Navigator.pushNamed(context, MyRoutes.homeRoute);
// },
// )
],
),
)
],
),
),
),
);
}
BorderRadius newMethod() => BorderRadius.circular(20);
}
Hi All, I'm a beginner to flutter and I'm trying to add validator to widget but I'm not getting the validation when I run the application.
I searched and tried the ways to do it but I didn't get the desired outcome.
Can you guys look into my code and suggest the right way.
no errors found but validation is not working.
First assign TextEditingController to your both fields.
final TextEditingController _controllerUserName = TextEditingController();
final TextEditingController _controllerPassword = TextEditingController();
And also assign autovalidateMode to your text field so you can validate at user input like this. It's not necessary it's optional but you can add it to validate your field on input field changes. Although you can validate your form at submission time.
TextFormField(
decoration: const InputDecoration(
hintText: "Enter User name", labelText: "Username "),
initialValue: "",
validator: (String? value) {
if (value !=null && value.isEmpty ) {
return "User name cannot be empty";
}
return null;
},
onChanged: (value) {
setState(() {});
},
autovalidate : AutovalidateMode.onUserInteraction,
controller:_controllerUserName
),
And also you have not validate your form at submission time. try this
moveToHome(BuildContext) async{
if (_formkey.currentState.validate()) {
Navigator.pushNamed(context, MyRoutes.homeRoute);
}
}

Not able to post http request using TextEditingController variable in JSON body

I am not able to post http request using TextEditingController in JSON body, but same code is working if I directly pass the string to JSON body
class _FormPageState extends State<FormPage> {
late String name1;
late String email1;
late String phone1;
late String pass1;
late String pass2;
TextEditingController name = new TextEditingController();
TextEditingController email = new TextEditingController();
TextEditingController phone = new TextEditingController();
TextEditingController password = new TextEditingController();
TextEditingController confirmpassword = new TextEditingController();
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Form(
key: _formkey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 70,
child: Image.network(
"https://protocoderspoint.com/wp-content/uploads/2020/10/PROTO-CODERS-POINT-LOGO-water-mark-.png"),
),
SizedBox(
height: 15,
),
Padding(
padding:
const EdgeInsets.only(bottom: 15, left: 10, right: 10),
child: TextFormField(
controller: name,
keyboardType: TextInputType.text,
decoration: buildInputDecoration(Icons.person, "Full Name"),
validator: (String? value) {
if (value!.isEmpty) {
return "Please enter name";
}
return null;
},
onSaved: (String? name) {},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 15, left: 10, right: 10),
child: TextFormField(
controller: email,
keyboardType: TextInputType.text,
decoration: buildInputDecoration(Icons.email, "Email"),
validator: (String? value) {
if (value!.isEmpty) {
return "Please enter email";
}
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return "Please enter valid email";
}
return null;
},
onSaved: (String? email) {},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 15, left: 10, right: 10),
child: TextFormField(
controller: phone,
keyboardType: TextInputType.number,
decoration: buildInputDecoration(Icons.phone, "Phone No"),
validator: (String? value) {
if (value!.isEmpty) {
return "Please enter phone";
}
if (value.length < 9) {
return "Please enter valid phone";
}
return null;
},
onSaved: (String? phone) {},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 15, left: 10, right: 10),
child: TextFormField(
controller: password,
keyboardType: TextInputType.text,
decoration: buildInputDecoration(Icons.lock, "Password"),
validator: (String? value) {
if (value!.isEmpty) {
return "Please enter password";
}
return null;
},
),
),
Padding(
padding:
const EdgeInsets.only(bottom: 15, left: 10, right: 10),
child: TextFormField(
controller: confirmpassword,
obscureText: true,
keyboardType: TextInputType.text,
decoration:
buildInputDecoration(Icons.lock, "Confirm Password"),
validator: (String? value) {
if (value!.isEmpty) {
return "Please enter re-password";
}
if (password.text != confirmpassword.text) {
return "Password Do not match";
}
return null;
},
),
),
SizedBox(
width: 200,
height: 50,
child: RaisedButton(
color: Colors.redAccent,
onPressed: () {
if (_formkey.currentState!.validate()) {
RegistrationUser();
print("Successful");
} else {
print("Unsuccessfull");
}
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
side: BorderSide(color: Colors.blue, width: 2)),
textColor: Colors.white,
child: Text("Submit"),
),
)
],
),
),
),
),
);
}
Future RegistrationUser() async {
var APIURL =
"https://heythere14168465465.000webhostapp.com/registration.php";
name1 = name.text;
email1 = email.text;
phone1 = phone.text;
pass1 = password.text;
pass2 = 'd55';
print(name1);
print(email1);
print(phone1);
print(pass1);
http.Response reponse = await http.post(Uri.parse(APIURL), body: {
"name": name1,
"email": email1,
"phone": phone1,
"password": pass1
});
//getting response from php code, here
var data = jsonDecode(reponse.body);
print("DATA: ${data}");
}
}