User Entered Data is not saved on Firebase_realtime_database.I tried making a personal information form . But when I click on submit button , the data entred by user is not saving in firebase(real-time database). What could be error?
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import 'package:firebase_database/firebase_database.dart';
class DonorRegistration extends StatefulWidget {
#override
DonorRegistration({Key key}) : super(key: key);
#override
_DonorRegistrationState createState() => _DonorRegistrationState();
}
}
class _DonorRegistrationState extends State<DonorRegistration> {
var data;
bool autoValidate = true;
bool readOnly = false;
bool showSegmentedControl = true;
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
final ValueChanged _onChanged = (val) => print(val);
var currentItemSelected3;
bool disabledropdown = true;
final TextEditingController _nameController = TextEditingController();
String _gender = 'Male';
final TextEditingController _ageController = TextEditingController();
final dbRef = FirebaseDatabase.instance.reference().child("donor");
This is UI area
enter code here
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromRGBO(1500, 0, 5, 1),
title: Text('Donor Registration'),
),
body: Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
height: 100,
width: 100,
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 65.0,
child: Image.asset('lib/assets/logo.png'))),
FormBuilder(
// context,
key: _fbKey,
// autovalidate: true,
readOnly: false,
child: Column(
children: <Widget>[
Text('Personal Information'),
SizedBox(height: 15),
FormBuilderTextField(
attribute: 'Name',
controller: _nameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(
Icons.account_circle,
color: Color.fromRGBO(255, 0, 0, 1),
),
labelText: 'Full Name',
hintText: 'Enter Your Full name',
),
validators: [
FormBuilderValidators.required(
errorText: 'This field required')
],
keyboardType: TextInputType.name,
//controller: _nameController,
),
SizedBox(height: 25),
FormBuilderRadioGroup(
attribute: 'radio_group',
decoration: const InputDecoration(
//value: gender,
border: OutlineInputBorder(),
icon: Icon(
Icons.person_pin,
color: Color.fromRGBO(255, 0, 0, 1),
),
labelText: 'Gender'),
onChanged: _onChanged,
options: [
FormBuilderFieldOption(value: 'M', child: Text('Male')),
FormBuilderFieldOption(value: 'F', child: Text('Female')),
FormBuilderFieldOption(value: 'O', child: Text('Other')),
]
.map((_gender) => FormBuilderFieldOption(
value: _gender,
child: Text('$_gender'),
))
.toList(growable: false),
validators: [
FormBuilderValidators.required(
errorText: 'This field required')
],
),
SizedBox(height: 15),
FormBuilderTextField(
attribute: 'age',
// autovalidate: true,
controller: _ageController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Age',
icon: Icon(
Icons.confirmation_number,
color: Color.fromRGBO(255, 0, 0, 1),
),
),
validators: [
FormBuilderValidators.required(
errorText: 'This field required')
],
keyboardType: TextInputType.number,
),
FormBuilderSwitch(
label: Text('I Accept the tems and conditions'),
attribute: 'accept_terms_switch',
initialValue: true,
onChanged: _onChanged,
),
SizedBox(height: 15),
],
),
),
Row(
children: <Widget>[
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
'Submit',
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (_fbKey.currentState.validate()) {
dbRef.push().set({
"name": _nameController.text,
"age": _ageController.text,
"gender": _gender,
"disease": _diseaseController.text,
"blood_group": _blood,
"body_part": _donate,
"Hospitals": _hospital,
}).then((_) {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Successfully Added')));
_ageController.clear();
_nameController.clear();
}).catchError((onError) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text(onError)));
});
} else {
print(_fbKey.currentState.value);
print('validation failed');
}
},
),
),
SizedBox(width: 20),
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
'Reset',
style: TextStyle(color: Colors.white),
),
onPressed: () {
_fbKey.currentState.reset();
},
)),
],
),
],
),
),
);
}
#override
void dispose() {
super.dispose();
_ageController.dispose();
_nameController.dispose();
}
}
please tell me what could be errors.
Related
This is a part of a project regarding feedback forms.
I already manage to create the validation form properly thanks to the answers here in StackOverflow developers.
But the problem is creating this regular expression which seems to not work on the validation form. I found in flutter docs the Iterable but I do not know how can I implement it on the dart page.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class SimpleDialog extends StatelessWidget {
// ignore: prefer_typing_uninitialized_variables
final title;
const SimpleDialog(this.title, {super.key});
#override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Alert'),
content: Text(title),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'))
],
);
}
}
class FeedbackPage extends StatefulWidget {
const FeedbackPage({super.key});
#override
State<FeedbackPage> createState() => _FeedbackPageState();
}
class _FeedbackPageState extends State<FeedbackPage> {
final nameOfuser = TextEditingController();
final emailOfuser = TextEditingController();
final messageOfuser = TextEditingController();
final _formKey = GlobalKey<FormState>();
List<bool> isTypeSelected = [false, false, false, true, true];
#override
Widget build(BuildContext context) {
return Scaffold(
// AppBar para sa taas ng design
appBar: AppBar(
centerTitle: true,
title: const Text(
"PicLeaf",
style: TextStyle(
color: Color.fromRGBO(102, 204, 102, 1.0),
fontWeight: FontWeight.bold),
),
backgroundColor: Colors.white,
shadowColor: const Color.fromARGB(255, 95, 94, 94),
),
//body of the application
backgroundColor: const Color(0xffeeeeee),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const SizedBox(
height: 20,
),
const Text(
"Feedback",
style: TextStyle(
fontSize: 30.0,
fontFamily: 'RobotoBold',
fontWeight: FontWeight.bold,
color: Color.fromRGBO(102, 204, 102, 1.0)),
),
const Text(
"Give us your feedback!",
style: TextStyle(
fontSize: 18.0,
fontFamily: 'RobotoMedium',
),
),
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
const SizedBox(height: 16.0),
TextFormField(
controller: nameOfuser,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: "Name",
border: OutlineInputBorder(),
),
validator: (nameOfuser) {
if (nameOfuser == null || nameOfuser.isEmpty) {
return 'Please enter your Name';
}
return null;
},
),
const SizedBox(height: 8.0),
TextFormField(
controller: emailOfuser,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: "Email",
border: OutlineInputBorder(),
),
validator: (emailOfuser) {
if (emailOfuser == null || emailOfuser.isEmpty) {
String emailOfuser1 = emailOfuser.toString();
String pattern = r'\w+#\w+\.\w+';
if (RegExp(pattern).hasMatch(emailOfuser1)) {
return 'Please enter your Email Properly';
} else {
return 'Please enter your Email';
}
}
return null;
},
),
const SizedBox(height: 8.0),
TextFormField(
controller: messageOfuser,
maxLines: 6,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: "Message",
border: OutlineInputBorder(),
),
validator: (messageOfuser) {
if (messageOfuser == null || messageOfuser.isEmpty) {
return 'Please enter your Message';
}
return null;
},
),
const SizedBox(height: 8.0),
MaterialButton(
height: 50.0,
minWidth: double.infinity,
color: const Color.fromRGBO(102, 204, 102, 1.0),
onPressed: () {
if (_formKey.currentState!.validate()) {
showDialog(
context: context,
builder: (BuildContext context) {
return const SimpleDialog(
'Feedback Submitted');
});
Map<String, dynamic> data = {
"Name": nameOfuser.text,
"Email": emailOfuser.text,
"Message": messageOfuser.text,
"Time": FieldValue.serverTimestamp(),
};
setState(() {
nameOfuser.clear();
emailOfuser.clear();
messageOfuser.clear();
});
FirebaseFirestore.instance
.collection("FeedbackMessages")
.add(data);
}
},
child: const Text(
"SUBMIT",
style: TextStyle(
fontFamily: 'RobotoBold',
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
const SizedBox(
height: 10,
),
Container(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
child: const Text(
'Contact Us!',
style: TextStyle(
fontSize: 30,
fontFamily: 'RobotoBold',
color: Color.fromRGBO(102, 204, 102, 1.0)),
textAlign: TextAlign.center,
),
),
Column(
children: <Widget>[
Container(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
margin: const EdgeInsets.symmetric(horizontal: 0),
child: TextButton.icon(
// <-- TextButton
onPressed: () {},
icon: const Icon(
Icons.facebook,
color: Colors.black,
size: 35.0,
),
label: const Text(
'facebook.com/picleaf',
style: TextStyle(fontFamily: 'RobotoMedium'),
),
style: TextButton.styleFrom(
foregroundColor: Colors.black,
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(20, 0, 20, 10),
margin: const EdgeInsets.symmetric(horizontal: 0),
child: TextButton.icon(
// <-- TextButton
onPressed: () {},
icon: const Icon(
Icons.email,
color: Colors.black,
size: 35.0,
),
label: const Text(
'picleaf#gmail.com',
style: TextStyle(fontFamily: 'RobotoMedium'),
),
style: TextButton.styleFrom(
foregroundColor: Colors.black,
),
)),
],
)
],
),
),
),
],
),
));
}
}
You can use this validator:
validator: (emailOfuser) {
if (emailOfuser == null || emailOfuser.isEmpty) {
return 'Please enter your Email';
} else if (emailOfuser.isNotEmpty) {
String emailOfuser1 = emailOfuser.toString();
String pattern = r'\w+#\w+\.\w+';
if (RegExp(pattern).hasMatch(emailOfuser1) == false) {
return 'Please enter your Email Properly';
}
}
return null;
},
try to implement like this:
import 'package:flutter/material.dart';
class EmailValidationForm extends StatefulWidget {
const EmailValidationForm({Key? key}) : super(key: key);
#override
State<EmailValidationForm> createState() => _EmailValidationFormState();
}
class _EmailValidationFormState extends State<EmailValidationForm> {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Email Validation'),
),
body: Form(
key: formKey,
child: Column(
children: [
TextFormField(
autofocus: false,
maxLength: 300,
keyboardType: TextInputType.emailAddress,
autocorrect: false,
validator: (email) {
if (email!.isEmpty) {
return 'required field';
} else if (email.trim().contains(' ')) {
return 'contain space';
} else if (!emailValid(email)) {
return 'invalid email';
}
return null;
},
onSaved: (email) {
return debugPrint(email);
},
),
ElevatedButton(
onPressed: () {
if (formKey.currentState!.validate()) {
formKey.currentState!.save();
}
},
child: const Text('Validate')),
],
),
),
);
}
}
bool emailValid(String email) {
final RegExp regex = RegExp(
r"^(([^<>()[\]\\.,;:\s#\']+(\.[^<>()[\]\\.,;:\s#\']+)*)|(\'.+\'))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$");
return regex.hasMatch(email.trim());
}
I am new to flutter.
I do not understand why this error appearing : The element type 'MatchValidator' can't be assigned to the list type 'FieldValidator'.
I am using package form_field_validator in my reset password screen.
In TextFormField Validator i am using MultiValidator() in which RequiredValidator, MaxLengthValidator, MinLenghtValidator are working correctly but when i am using MatchValidator it is causing error that is '''''''The element type 'MatchValidator' can't be assigned to the list type 'FieldValidator'.''''''''
Can anyone please describe what to do
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:form_field_validator/form_field_validator.dart';
import 'package:my_treat/common/constants.dart';
import 'package:my_treat/common/common.dart';
import 'package:my_treat/common/AppTheme.dart';
import 'package:my_treat/screens/login_screen.dart';
class ResetPasswordScreen extends StatefulWidget {
const ResetPasswordScreen({Key? key}) : super(key: key);
static const routeName = 'reset-password';
#override
State<ResetPasswordScreen> createState() => _ResetPasswordScreenState();
}
class _ResetPasswordScreenState extends State<ResetPasswordScreen> {
bool isHidden1 = true;
bool isHidden2 = true;
GlobalKey<FormState> formkey = GlobalKey<FormState>();
void togglePasswordView1() {
setState(() {
isHidden1 = !isHidden1;
});
}
void togglePasswordView2() {
setState(() {
isHidden2 = !isHidden2;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: double.infinity,
padding: EdgeInsets.only(left: 20, right: 20),
decoration: Common.commonBoxDecoration,
child: Form(
key: formkey,
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: Common.displayHeight(context) * 0.04),
Common.backButton(() {
Navigator.of(context).pop();
}),
SizedBox(height: Common.displayHeight(context) * 0.02),
Image(image: AssetImage('assets/images/my-treat.png')),
SizedBox(height: Common.displayHeight(context) * 0.06),
Align(
child: Text(
'Reset Password',
style: TextStyle(fontSize: 23, color: AppColors.white),
),
),
SizedBox(height: Common.displayHeight(context) * 0.07),
TextFormField(
cursorColor: AppColors.darkGrey,
maxLength: 15,
keyboardType: TextInputType.visiblePassword,
textInputAction: TextInputAction.next,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp("[a-zA-Z0-9!##\$%^&*.]")),
],
obscureText: isHidden1,
validator: MultiValidator(
[
RequiredValidator(errorText: 'Required'),
MaxLengthValidator(15,
errorText: 'Should Not Greater than 15 Characters'),
MinLengthValidator(7,
errorText: 'Should Be Greater than 7 Characters'),
// MatchValidator(errorText: 'sdf'),
],
),
decoration: InputDecoration(
counterText: '',
prefixIcon: Icon(
Icons.lock_open_sharp,
color: AppColors.darkGrey,
),
hintText: 'Password',
suffixIcon: IconButton(
icon: Icon(
isHidden1 ? Icons.visibility : Icons.visibility_off),
color: AppColors.lightGrey,
onPressed: togglePasswordView1,
),
fillColor: AppColors.white,
filled: true,
border: Common.commonOutlineInputBorder,
),
),
SizedBox(height: Common.displayHeight(context) * 0.02),
TextFormField(
cursorColor: AppColors.darkGrey,
maxLength: 15,
keyboardType: TextInputType.visiblePassword,
textInputAction: TextInputAction.done,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp("[a-zA-Z0-9!##\$%^&*.]")),
],
validator: MultiValidator(
[
RequiredValidator(errorText: 'Required'),
MinLengthValidator(7,
errorText: 'Should Be Greater than 7 Characters'),
MaxLengthValidator(15,
errorText: 'Should Not Greater than 15 Characters')
],
),
obscureText: isHidden2,
decoration: InputDecoration(
counterText: '',
prefixIcon: Icon(
Icons.lock_open_sharp,
color: AppColors.darkGrey,
),
hintText: 'Confirm Password',
suffixIcon: IconButton(
icon: Icon(
isHidden2 ? Icons.visibility : Icons.visibility_off),
color: AppColors.lightGrey,
onPressed: togglePasswordView2,
),
fillColor: AppColors.white,
filled: true,
border: Common.commonOutlineInputBorder,
),
),
SizedBox(height: Common.displayHeight(context) * 0.12),
SizedBox(
height: Common.displayHeight(context) * 0.07,
child: Common.customElevatedButton(
Constants.update,
() {
if (formkey.currentState!.validate()) {
Navigator.of(context).pushNamedAndRemoveUntil(
LoginScreen.routeName,
(Route<dynamic> route) => false);
}
},
),
),
],
),
),
),
),
);
}
}
enter image description here
I created a database with sqflite on the user's phone. The words entered by the user are saved in the main list.
When you press the icon next to it, it is added to the favorite list, but when the user exits the application, the favorite list is reset.
The main list is the same, there is no problem with it.
When a word is deleted from the main list, it is also deleted from the favorite. But the only problem is that when the favorite list comes out and enters, it resets and writes blank.
How can I make the favorite list stay the same when I exit the application?
This is home page dart file.
class WordList extends StatefulWidget {
const WordList({Key key}) : super(key: key);
#override
State<StatefulWidget> createState() {
return _WordListState();
}
}
class _WordListState extends State {
var dbHelper = DbHelper();
List<Word> words;
List<Word> favoriteWords = [];
int wordCount = 0;
int fwordCount = 0;
#override
void initState() {
getWords();
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: Text(
"ShopList",
style: GoogleFonts.caveat(
textStyle: const TextStyle(
color: Colors.white,
fontSize: 35,
letterSpacing: 1,
fontWeight: FontWeight.w700,
),
),
),
leading: const Padding(
padding: EdgeInsets.all(2.0),
child: Icon(
Icons.shopping_cart,
size: 35.0,
),
),
backgroundColor: Colors.deepPurple,
bottom: const TabBar(
indicatorColor: Colors.deepPurpleAccent,
automaticIndicatorColorAdjustment: false,
labelColor: Colors.deepPurple,
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(7), topRight: Radius.circular(7)),
color: Colors.white),
tabs: [
Tab(
child: Align(
alignment: Alignment.center,
child: Icon(Icons.article_rounded),
),
),
Tab(
child: Align(
alignment: Alignment.center,
child: Icon(Icons.favorite),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
goToWordAdd();
},
child: const Icon(Icons.add),
tooltip: "Add New Item",
splashColor: Colors.white,
backgroundColor: Colors.deepPurple,
),
body: TabBarView(
children: [
ListView.builder(
itemCount: wordCount,
itemBuilder: (BuildContext context, int position) {
return Card(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(3.0),
child: ListTile(
title: SelectableText(
words[position].word,
cursorColor: Colors.purple,
showCursor: false,
toolbarOptions: const ToolbarOptions(
copy: true,
selectAll: true,
cut: false,
paste: false),
style: GoogleFonts.caveat(
textStyle: const TextStyle(
color: Colors.deepPurple,
fontSize: 25.0,
fontWeight: FontWeight.w700,
),
),
),
subtitle: SelectableText(
words[position].description,
cursorColor: Colors.purple,
showCursor: false,
toolbarOptions: const ToolbarOptions(
copy: true,
selectAll: true,
cut: false,
paste: false),
style: GoogleFonts.caveat(
textStyle: const TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {
if (!favoriteWords
.contains(words[position])) {
favoriteWords.add(words[position]);
}
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(5.0),
side: const BorderSide(
color:
Colors.deepPurpleAccent)))),
child: const Icon(
Icons.favorite,
color: Colors.white,
),
),
IconButton(
color: Colors.blueGrey,
icon: const Icon(Icons.delete),
tooltip: 'Delete Item',
onPressed: () {
goToDelete(words[position]);
},
),
],
),
);
},
),
favoriteWords.isEmpty
? const Center(
child: Text(
'Ürünlerini favorilerine ekle, almayı unutma! ',
style: TextStyle(
color: Colors.deepPurple,
fontWeight: FontWeight.bold),
),
)
: ListView.builder(
itemCount: fwordCount,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(3.0),
child: ListTile(
title: SelectableText(
favoriteWords[index].word,
cursorColor: Colors.purple,
showCursor: false,
toolbarOptions: const ToolbarOptions(
copy: true,
selectAll: true,
cut: false,
paste: false),
style: const TextStyle(fontSize: 17.0),
),
subtitle: SelectableText(
favoriteWords[index].description,
cursorColor: Colors.purple,
showCursor: false,
toolbarOptions: const ToolbarOptions(
copy: true,
selectAll: true,
cut: false,
paste: false),
style: const TextStyle(fontSize: 17.0),
),
),
),
),
ElevatedButton(
onPressed: () {
setState(() {
favoriteWords.remove(favoriteWords[index]);
});
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.deepPurple,
),
),
child: const Icon(
Icons.remove,
color: Colors.white,
),
),
],
),
);
},
),
],
),
),
);
}
void goToWordAdd() async {
bool result = await Navigator.push(
context, MaterialPageRoute(builder: (context) => const WordAdd()));
if (result != null) {
if (result) {
getWords();
}
}
}
void getWords() {
var wordsFuture = dbHelper.getWords();
wordsFuture.then((data) {
setState(() {
words = data;
wordCount = data.length;
});
});
}
void goToDelete(Word word) async {
await dbHelper.delete(word.id);
favoriteWords.remove(word);
getWords();
}
}
I am creating a app using flutter and firebase. but when i am trying to create a user instance it is showing this error:- "PlatformException(ERROR_INVALID_EMAIL, The email address is badly formatted., null)"
I am attaching the code.///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
import 'package:chatbox/services/auth.dart';
import 'package:chatbox/services/database.dart';
import 'package:chatbox/views/chatRoom.dart';
import 'package:chatbox/widgets/widget.dart';
import 'package:flutter/material.dart';
class SignUp extends StatefulWidget {
final Function toggle;
SignUp(this.toggle);
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
bool isLoading = false;
DatabaseMethods databaseMethods=new DatabaseMethods();
AuthMethods authMethods = new AuthMethods();
final formKey = GlobalKey<FormState>();
TextEditingController userNameTextEditingController =
new TextEditingController();
TextEditingController emailTextEditingController =
new TextEditingController();
TextEditingController passwordTextEditingController =
new TextEditingController();
signMeUp() async {
if(formKey.currentState.validate()) {
Map<String,String> userInfoMap={
"email": emailTextEditingController.text,
"name" : userNameTextEditingController.text,
};
setState(() {
isLoading =true;
});
authMethods.signUpWithEmailAndPassword(emailTextEditingController.text, passwordTextEditingController.text)
.then((val){
// print("${val.uid}");
databaseMethods.uploadUserInfo(userInfoMap);
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context)=>chatRoom(),
));
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBarMain(context),
body: isLoading ? Container(
child: Center(child: CircularProgressIndicator()) ,
) : SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height - 50,
alignment: Alignment.bottomCenter,
padding: EdgeInsets.symmetric(horizontal: 24),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Form(
key: formKey,
child: Column(
children: [
TextFormField(
validator: (val) {
return val.isEmpty || val.length < 2 ? "invalid" : null;
},
controller: userNameTextEditingController,
style: simpleTextstyle(),
decoration: textFieldInputDecoration("username"),
),
TextFormField(
validator: (val){
return RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(val) ? null : "Enter correct email";
},
controller: emailTextEditingController,
style: simpleTextstyle(),
decoration: textFieldInputDecoration("email"),
),
TextFormField(
validator: (val) {
return val.length < 6
? "Enter Password 6+ characters"
: null;
},
controller: passwordTextEditingController,
style: simpleTextstyle(),
obscureText: true,
decoration: textFieldInputDecoration("password"),
),
],
),
),
SizedBox(
height: 8,
),
Container(
alignment: Alignment.centerRight,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
"forget password",
style: simpleTextstyle(),
),
)),
SizedBox(
height: 8,
),
GestureDetector(
onTap: () {
signMeUp();
},
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.symmetric(vertical: 20),
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
const Color(0xff007EF4),
const Color(0xff2A75BC)
]),
borderRadius: BorderRadius.circular(40)),
child: Text(
"Sign up",
style: TextStyle(color: Colors.white, fontSize: 17),
),
),
),
SizedBox(
height: 8,
),
Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.symmetric(vertical: 20),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(40)),
child: Text(
"Sign up with google",
style: TextStyle(color: Colors.black, fontSize: 17),
),
),
SizedBox(
height: 8,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Already have an account?",
style: meadiumTextstyle(),
),
GestureDetector(
onTap: (){
widget.toggle();
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 8),
child: Text("Sign in Now",
style: TextStyle(
color: Colors.white,
fontSize: 17,
decoration: TextDecoration.underline,
)),
),
),
],
),
SizedBox(
height: 60,
),
]),
),
),
);
}
}
Assume email is correct
From issue https://github.com/FirebaseExtended/flutterfire/issues/1760#issuecomment-570766212 and https://github.com/FirebaseExtended/flutterfire/issues/1760#issuecomment-613303831
email text field value might contain white space
You can use emailTextEditingController.text.trim()
code snippet
authMethods.signUpWithEmailAndPassword(emailTextEditingController.text.trim(), passwordTextEditingController.text)
...
Map<String,String> userInfoMap={
"email": emailTextEditingController.text.trim(),
"name" : userNameTextEditingController.text,
};
You can also use package https://pub.dev/packages/email_validator to validate email
code snippet
import 'dart:core';
import 'package:email_validator/email_validator.dart';
void main() {
const String email = 'fredrik.eilertsen#gail.com';
final bool isValid = EmailValidator.validate(email);
print('Email is valid? ' + (isValid ? 'yes' : 'no'));
}
The error is because your email id is not in the correct format. Try editing your email id.
In your email validator add this.
Validator(val){
if(!val.contains("#")){
retrun enter a valid email}
else{ return null}
}
I wanted to know as to how can I submit the form which will print the user data from a previous page as well as the current page it is in? This will help me further when I am trying to update user data on firestore. I couldn't find a solution hence I would really appreciate whatever help I can get! :)
edit:
For anyone who didn't get what I was trying to say
I have the textfields of First Name, Last name and age in one page for which the user will press on the next button when done entering. In the final registration page which consists of email and password textfields contains the Register button which will register the user. I want to press Register on the final registration page which will print the data entered in the previous page as well as the current page. I wanted to know how can I achieve that so that later on I can update the user data to firestore
previous page
class UserDetails extends StatefulWidget {
#override
_UserDetailsState createState() => _UserDetailsState();
}
enum Gender{
Male, Female, Others
}
class _UserDetailsState extends State<UserDetails> {
String userFirstName;
String userLastName;
String user_age;
int group_value = -1;
Gender _gender = Gender.Male;
final formkeyDetails = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
//final _userProvider = Provider.of<UserProvider>(context);
final _firstName = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: TextFormField(
autofocus: false,
keyboardType: TextInputType.text,
/*onChanged: (value){
_userProvider.changeFirstName(value);
},
*/
validator: (value) {
if(value.isEmpty)
{
return 'Field cannot be empty';
}
return null;
},
onSaved: (value)=> userFirstName = value,
decoration: InputDecoration(
hintText: 'Enter First Name',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
);
final _lastName = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: TextFormField(
autofocus: false,
keyboardType: TextInputType.text,
/* onChanged: (value){
_userProvider.changeLastName(value);
}
,
*/
validator: (value) {
if(value.isEmpty)
{
return 'Field cannot be empty';
}
return null;
},
onSaved: (value)=> userLastName = value,
decoration: InputDecoration(
hintText: 'Enter Last Name',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
);
final _userAge = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: TextFormField(
keyboardType: TextInputType.number,
autofocus: false,
/* onChanged: (value){
_userProvider.changeAge(value);
},
*/
validator: (value) {
if(value.isEmpty)
{
return 'Field cannot be empty';
}
return null;
},
onSaved: (value)=> user_age = value,
decoration: InputDecoration(
hintText: 'Enter Age',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
);
final _male = Radio(
value: Gender.Male,
activeColor: Colors.black,
groupValue: _gender,
onChanged: (Gender value){
setState(() {
print(value);
_gender = value;
});
},
);
final _female = Radio(
activeColor: Colors.black,
value: Gender.Female,
groupValue: _gender,
onChanged: (Gender value){
setState(() {
print(value);
_gender = value;
});
},
);
final _others = Radio(
activeColor: Colors.black,
value: Gender.Others,
groupValue: _gender,
onChanged: (Gender value){
setState(() {
print(value);
_gender = value;
});
},
);
return Scaffold(
backgroundColor: Colors.yellow,
body: Container(
child: Form(
key: formkeyDetails,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Register",
style: TextStyle(fontSize: 64.0, fontWeight: FontWeight.bold),),
SizedBox(height: 50,),
_firstName,
SizedBox(height: 20,),
_lastName,
SizedBox(height: 20,),
_userAge,
SizedBox(height: 30,),
Row(
crossAxisAlignment: CrossAxisAlignment.center ,
children: <Widget>[
Text(" Gender: ", style: TextStyle(fontSize: 20.0),),
_male,
Text("Male"),
_female,
Text("Female"),
_others,
Text("Others"),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.center ,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
FloatingActionButton.extended(
heroTag: "prev_button",
backgroundColor: Colors.yellow,
foregroundColor: Colors.black,
onPressed: ()=> Navigator.push(context, MaterialPageRoute(builder: (context)=>UserLogin())),
label: Text("Prev", style: TextStyle(fontWeight: FontWeight.bold),)
),
FloatingActionButton.extended(
heroTag: "next_button",
backgroundColor: Colors.yellow,
foregroundColor: Colors.black,
onPressed: ()=> Navigator.push(context, MaterialPageRoute(builder: (context)=>UserReg())),
label: Text("Next", style: TextStyle(fontWeight: FontWeight.bold),)
),
],
),
],
),
),
),
);
}
}
Current page (which will print the contents of the previous page as well)
class UserReg extends StatefulWidget {
UserReg({this.auth});
final BaseAuth auth;
#override
State<StatefulWidget> createState() => _UserRegState();
}
class _UserRegState extends State<UserReg> {
final formkey = GlobalKey<FormState>();
static String emailValidator(String value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (!regex.hasMatch(value)) {
return 'Email format is invalid';
} else {
return null;
}
}
static String pwdValidator(String value) {
if (value.length <= 6) {
return 'Password must be longer than 8 characters';
} else {
return null;
}
}
bool _validateAndSave()
{
final form2 = formkey.currentState;
final form1 = formkeyDetails.currentState;
if(form2.validate())
{
form.save();
return true;
}
return false;
}
void _validateAndSubmit() async
{
if(_validateAndSave()) {
try {
String userId = await Auth().signUp(rEmail, rPass);
await Auth().sendEmailVerification();
formkey.currentState.reset();
print('Registered! $userId, sent email verification');
}
catch (e) {
print('Error: $e');
}
}
}
final notValidIcon = Icon(
Icons.error,
color: Colors.pink,
);
static String rEmail;
static String rPass;
#override
Widget build(BuildContext context) {
//final userProvider = Provider.of<UserProvider>(context);
final _regEmail = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
validator: (value) {
if(value.isEmpty)
{
return 'Email cannot be empty';
}
else
emailValidator(value);
return null;
},
/*onChanged: (value){
userProvider.changeEmail(value);
},
*/
onSaved: (value)=> rEmail = value,
decoration: InputDecoration(
hintText: 'Enter Email Address',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
);
final _regpass = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: TextFormField(
obscureText: true,
autofocus: false,
validator: pwdValidator,
/*onChanged: (value){
userProvider.changePassword(value);
},
*/
onSaved: (value)=> rPass = value,
decoration: InputDecoration(
hintText: 'Enter password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
);
final _confPass = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: TextFormField(
obscureText: true,
autofocus: false,
validator: (value){
if(value != rPass)
{
return("Password does not match");
}
return pwdValidator(value);
},
/*
onChanged: (value){
userProvider.changePassword(value);
},
*/
onSaved: (value)=> rPass = value,
decoration: InputDecoration(
hintText: 'Enter password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
);
return new Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Colors.yellow,
body: Container(
height: MediaQuery.of(context).size.height,
child: Form(
key: formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: MediaQuery.of(context).size.height *0.2,),
Text('Register',
style:TextStyle(
fontWeight: FontWeight.bold,
fontSize: 64,
),
),
SizedBox(height: 100,),
_regEmail,
SizedBox(height: 20,),
_regpass,
SizedBox(height:30),
//_confRegPass,
SizedBox(height: 30,),
FloatingActionButton.extended(
heroTag: "Register_Button",
backgroundColor: Colors.yellow,
foregroundColor: Colors.black,
onPressed: (){
_validateAndSubmit();
//userProvider.saveUser();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context)=>UserLogin()));
},
label: Text("Register", style: TextStyle(fontWeight: FontWeight.bold),)
),
SizedBox(height: 20,),
FlatButton(
child: Text('Already Registered? Sign in!'),
onPressed: ()=> Navigator.push(context, MaterialPageRoute(builder: (context)=>UserLogin())) ,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
FloatingActionButton.extended(
heroTag: "prev_button1",
backgroundColor: Colors.yellow,
foregroundColor: Colors.black,
onPressed: ()=> Navigator.pop(context), //Navigator.push(context, MaterialPageRoute(builder: (context)=>UserDetails())),
label: Text("Prev", style: TextStyle(fontWeight: FontWeight.bold),)
),
],
),
],
),
),
),
);
}
}
Instead of directly going to the next page, you can validate the form in the current page itself using
onPressed: () {
// Validate returns true if the form is valid, otherwise false.
if (formKey.currentState.validate()) {
//Navigation Logic
}
}
And if you want the data from the previous page then you can refer to https://flutter.dev/docs/cookbook/navigation/passing-data