I am creating a flutter app and I am using firestore as the backend. I intend to add data to the backend from the app on a button click. I have the needed variables for those data and also called an instance of firestore. The problem now is when I click on the add button, though the fields are created in firestore, the values are null. I have read what others have written about it from here but it looks like the solution provided here does not tackle my problem.
What could I be doing wrong? Below is an excerpt of my code and shot of my backend.
class SoftwareIssuesContactForm extends StatefulWidget {
#override
_SoftwareIssuesContactFormState createState() =>
_SoftwareIssuesContactFormState();
}
class _SoftwareIssuesContactFormState extends State<SoftwareIssuesContactForm> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
List<String> _semesters = <String>['', 'Semester 1', 'Semester 2',
'Semester 3', 'Semester 4', 'Semester 5', 'Semester 6', 'Semester 7',
'Semester 8'];
String _stNumber;
String _stEmail;
String _query;
String _dropdownError;
String _stPhone;
String _selectedItem;
bool _autoValidate = false;
String _semester = '';
String uid;
// Contact newContact = Contact();
final FocusNode myFocusNodeEmail = FocusNode();
final FocusNode myFocusNodeName = FocusNode();
TextEditingController studentNumberController = TextEditingController();
TextEditingController studentEmailController = TextEditingController();
TextEditingController queryController = TextEditingController();
TextEditingController studentPhoneNumberController = TextEditingController();
PageController _pageController;
#override
void dispose() {
myFocusNodeEmail.dispose();
myFocusNodeName.dispose();
_pageController?.dispose();
super.dispose();
}
#override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
_pageController = PageController();
}
// ignore: slash_for_doc_comments
/**********************************************************
######## FOR VALIDATING STUDENT NUMBER #######
*********************************************************/
String validateStudentNumber(String value){
if (value.isEmpty) {
return 'Student Number is required';
}
else {
return null;
}
}
// ignore: slash_for_doc_comments
/**********************************************************
######## FOR VALIDATING PHONE NUMBER #######
*********************************************************/
String validateStudentPhoneNumber(String value){
String pattern = r'(^(?:[+0]9)?[0-9]{10,12}$)';
RegExp regExp = RegExp(pattern);
if (value == null) return 'Phone Number is required';
// else if (value.length != 10) {
// return 'Phone Number must be of 10 digits';
// }
else if (!regExp.hasMatch(value)) {
return 'Enter a valid Phone Number';
}
return null;
}
// ignore: slash_for_doc_comments
/**********************************************************
######## FOR VALIDATING EMAIL ADDRESS #######
*********************************************************/
String validateStudentEmailAddress (String value){
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}'
r'\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = RegExp(pattern);
if (value.isEmpty) return 'Your Email Address is required';
if (!regex.hasMatch(value))
return 'Enter a valid Email Address';
else
return null;
}
// ignore: slash_for_doc_comments
/**********************************************************
######## FOR VALIDATING ENQUIRIES #######
*********************************************************/
String validateStudentQuery(String value){
if (value.isEmpty) {
return 'You forgot to state the problem...';
}
else {
return null;
}
}
// ignore: slash_for_doc_comments
/*******************************************************************
##### CHECKING IF FORM IS VALID BEFORE SUBMITTING ######
*******************************************************************/
bool validateAndSave(){
final form = _formKey.currentState;
if(form.validate()){
form.save();
return true;
}
else {
return false;
}
}
// ignore: slash_for_doc_comments
/**********************************************************
####### VALIDATING FORM BEFORE SUBMITTING ########
***********************************************************/
validateAndSubmit(){
if (validateAndSave()) {
try{
// Navigator.pushReplacement(context,
// MaterialPageRoute(builder: (context) => DashboardScreen()),
// );
/**********************************************************
####### SHOW DIALOG ON SUBMIT ########
***********************************************************/
return showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context){
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 6,
backgroundColor: Colors.transparent,
child: _buildDialogContent(context),
);
}
);
}
catch(e){
print(e);
}
}
else {
setState(() {
_autoValidate = true;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF56ccf2),
// backgroundColor: Colors.grey[100],
body: SafeArea(
top: false,
bottom: false,
child: SingleChildScrollView(
child: Container(
// height: 600,
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 30,),
child: Text(
"IT SUPPORT QUERY FORM",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
// fontStyle: FontStyle.italic,
),
),
),
Padding(
padding: EdgeInsets.only(
top: 10.0, bottom: 5.0, left: 15.0, right: 15.0),
child: Card(
elevation: 6,
child: Form(
key: _formKey,
autovalidate: _autoValidate,
child: ListView(
shrinkWrap: true, // use this
padding: EdgeInsets.symmetric(horizontal: 20.0),
children: <Widget>[
//===> Email Number Text Input starts from here <===
Padding(
padding: EdgeInsets.only(
top: 10.0, bottom: 6.0, left: 1.0, right: 1.0),
child: TextFormField(
autofocus: false,
focusNode: myFocusNodeEmail,
controller: studentNumberController,
keyboardType: TextInputType.emailAddress,
style: TextStyle(
fontSize: 16.0,
color: Colors.black),
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
// icon: Icon(Icons.person),
// hintText: 'Enter your first and last name',
labelText: 'Student Number',
),
validator: validateStudentNumber,
onSaved: (String val) {
_stNumber = val;
},
),
),
// Padding(
// padding: EdgeInsets.only(
// top: 5.0, bottom: 10.0, left: 1.0, right: 1.0),
// child: TextFormField(
// decoration: InputDecoration(
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(20.0),
// ),
// // icon: const Icon(Icons.phone),
// // hintText: 'Enter a phone number',
// labelText: 'Phone',
// ),
// keyboardType: TextInputType.phone,
// inputFormatters: [
// WhitelistingTextInputFormatter.digitsOnly,
// ],
// ),
// ),
//===> Email Address Text Input starts from here <===
Padding(
padding: EdgeInsets.only(
top: 1.0, bottom: 6.0, left: 1.0, right: 1.0),
child: TextFormField(
validator: validateStudentEmailAddress,
onSaved: (String val) {
_stEmail = val;
},
controller: studentEmailController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
// icon: const Icon(Icons.email),
// hintText: 'Enter a email address',
labelText: 'Student Email',
),
keyboardType: TextInputType.emailAddress,
style: TextStyle(
fontSize: 16.0,
color: Colors.black),
),
),
//===> Phone Number Text Input starts from here <===
Padding(
padding: EdgeInsets.only(
top: 1.0, bottom: 6.0, left: 1.0, right: 1.0),
child: TextFormField(
validator: validateStudentPhoneNumber,
onSaved: (String val) {
_stPhone = val;
},
controller: studentPhoneNumberController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
// icon: const Icon(Icons.email),
// hintText: 'Enter a email address',
labelText: 'Phone Number',
),
keyboardType: TextInputType.phone,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'^[()\d -]{1,15}$')),
],
style: TextStyle(
fontSize: 16.0,
color: Colors.black),
),
),
//===> Drop Down Menu starts from here <===
Padding(
padding: EdgeInsets.only(top: 1.0, bottom: 6.0, left: 1.0, right: 1.0),
child: FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
// icon: const Icon(Icons.color_lens),
labelText: 'Semester',
hintText: ("Semester"),
),
isEmpty: _semester == '',
child: Padding(
padding: EdgeInsets.only(left: 1.0, right: 130 , ),
child: Container(
// height: 55, //gives the height of the dropdown button
width: MediaQuery.of(context).size.width,
child: DropdownButtonHideUnderline( // to hide the default underline of the dropdown button
child: ButtonTheme(
alignedDropdown: true, //If false (the default), then the dropdown's menu will be wider than its button.
child: DropdownButton(
value: _semester,
isDense: true,
elevation: 5,
isExpanded: true,
onChanged: (String value) {
setState(() {
_semester = value; // saving the selected value
state.didChange(value);
});
},
items: _semesters.map((String value) {
return DropdownMenuItem(
value: value, // displaying the selected value
child: Text(value ?? '',
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
maxLines: 1,
softWrap: true,
),
);
}).toList(),
),
),
),
),
),
);
},
),
),
//===> Query Text Input starts from here <===
TextFormField(
validator: validateStudentQuery,
onSaved: (String val) {
_query = val;
},
controller: queryController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
),
// icon: const Icon(Icons.email),
// hintText: 'Enter your query',
labelText: 'Your Query',
),
keyboardType: TextInputType.text,
style: TextStyle(
fontSize: 16.0,
color: Colors.black),
maxLines: 3,
),
// ignore: slash_for_doc_comments
/**********************************************************
####### FOR SUBMIT BUTTON ########
***********************************************************/
Container(
// padding: EdgeInsets.only(left: 1.0, top: 10.0),
margin: EdgeInsets.only(top: 6.0, bottom: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Color(0xFF008ECC),
offset: Offset(0.0, 0.0),
//blurRadius: 20.0,
),
BoxShadow(
color: Color(0xFF008ECC),
offset: Offset(0.0, 0.0),
//blurRadius: 20.0,
),
],
gradient: LinearGradient(
colors: [
Color(0xFF008ECC), //Colors is Olympic blue
Color(0xFF008ECC),
],
begin: FractionalOffset(0.2, 0.2),
end: FractionalOffset(1.0, 1.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
child: MaterialButton(
onPressed: validateAndSubmit,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 10.0, horizontal: 65.0),
child: Text(
"Submit",
style: TextStyle(
color: Colors.white,
fontSize: 25.0,
),
),
),
)),
],
)),
),
),
],
),
),
)),
);
}
}
// ignore: slash_for_doc_comments
/**********************************************************
### IMPLEMENTATION OF _buildDialogContent METHOD ###
***********************************************************/
Widget _buildDialogContent(BuildContext context) => Container(
height: 230,
decoration: BoxDecoration(
color: Color(0xFF008ECC),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: EdgeInsets.all(12.0),
child: Container(
height: 80, width: 80,
child: Icon(MdiIcons.vote,
size: 90,
color: Color(0xFF56ccf2),
),
),
),
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.only(topLeft: Radius.circular(12),
topRight: Radius.circular(12)),
),
),
SizedBox(height: 24),
Padding(
padding: EdgeInsets.only(left: 5, right: 5),
child: Text("To submit the form tap Yes. tap No to edit the form".toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 17,
),
),
),
SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("No".toUpperCase(),
style: TextStyle(
color: Colors.white,
),
),
),
SizedBox(width: 8),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Color(0xFF008ECC),
offset: Offset(0.0, 0.0),
//blurRadius: 20.0,
),
BoxShadow(
color: Color(0xFF008ECC),
offset: Offset(0.0, 0.0),
//blurRadius: 20.0,
),
],
gradient: LinearGradient(
colors: [
Color(0xFF008ECC), //Colors is Olympic blue
Color(0xFF008ECC),
],
begin: FractionalOffset(0.2, 0.2),
end: FractionalOffset(1.0, 1.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
child: RaisedButton(
onPressed: () {
_saveInput();
// Navigator.of(context).pop();
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => DashboardScreen()),
);
},
color: Colors.white,
child: Text("Yes".toUpperCase(),
style: TextStyle(
color: Colors.redAccent,
),
),
),
),
],
),
],
),
);
//This function adds the needed data to firestore.
void _saveInput () async{
String uid;
String _stName;
String _stSemester;
String _stNumber;
String _stEmail;
String _query;
String _stPhone;
String _selectedItem;
//Creating reference object for firestore
final db = FirebaseFirestore.instance;
print(_stName);
await FirebaseFirestore.instance.collection('software_issues').doc().set({
'Uid': uid,
'Student Name': _stName,
'Student Semester': _stSemester,
'Student Number': _stNumber,
'Student Email': _stEmail,
'Student Query': _query,
'Student Phone Num': _stPhone,
'Selected Item': _selectedItem,
});
Can you try:
Firestore.instance.collection('software_issues').document().setData(
your data
);
set merge property to true if you want to update it.
Related
Below is the vehicle uploading details file code that uploads details on the firebase. It uploads city, vehicle type, and phone number. I wanted to search for vehicle in the specified city. So basically it matches the details of user. For example a person wants to book vehicle in city Lahore and vehicle type Car so this should search in database if anyone uploaded details matching the description and show it to the user.
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flash_chat/constants.dart';
import 'package:flash_chat/constraints/rounded_button.dart';
import 'package:flash_chat/screens/Home.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:image_picker/image_picker.dart';
class UploadingVehicle extends StatefulWidget {
static const id = 'uploading_vehicle';
#override
_UploadingVehicleState createState() => _UploadingVehicleState();
}
class _UploadingVehicleState extends State<UploadingVehicle> {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
bool showSpinner = false;
static String uCity;
String description;
String phoneNumber;
String uDropdownvalue = 'Hiace';
var vehicles = ['Car','Suzuki Bolan','Hiace'];
File _image1,_image2,_image3;
String id;
final Picker = ImagePicker();
_UploadingVehicleState();
_imgFromCamera() async {
final image = await Picker.pickImage(
source: ImageSource.camera, imageQuality: 50
);
setState(() {
_image1 = File(image.path);
});
}
_imgFromGallery(String id) async {
final image = await Picker.pickImage(
source: ImageSource.gallery, imageQuality: 50
);
if(id == 'A'){
setState(() {
_image1 = File(image.path);
});
}else if(id == 'B'){
setState(() {
_image2 = File(image.path);
});
}
else if(id == 'C'){
setState(() {
_image3 = File(image.path);
});
}
}
void _showPicker(context, String id) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return SafeArea(
child: Container(
child: new Wrap(
children: <Widget>[
new ListTile(
leading: new Icon(Icons.photo_library),
title: new Text('Photo Library'),
onTap: () {
_imgFromGallery(id);
Navigator.of(context).pop();
}),
new ListTile(
leading: new Icon(Icons.photo_camera),
title: new Text('Camera'),
onTap: () {
_imgFromCamera();
Navigator.of(context).pop();
},
),
],
),
),
);
}
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
title: Text('Upload vehicle'.toUpperCase(),
style: TextStyle(color: Colors.black)),
backgroundColor: Colors.yellowAccent.shade700,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back)),
actions: [
Icon(Icons.person),
],
),
body: SafeArea(
child: Container(
child: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(
height: 40,
),
Material(
elevation: 18,
shadowColor: Colors.black,
child: TextField(
style: TextStyle(
color: Colors.black,
),
decoration: kRegisterTextFieldDecoration.copyWith(
prefixIcon: Icon(Icons.location_city,
color: Colors.black,
),
hintText: 'Enter City',
fillColor: Colors.white,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
autofocus: true,
onChanged: (value){
uCity = value;
},
),
),
SizedBox(
height: 40,
),
Material(
elevation: 18,
shadowColor: Colors.black,
child: TextField(
style: TextStyle(
color: Colors.black,
),
keyboardType: TextInputType.number,
decoration: kRegisterTextFieldDecoration.copyWith(
prefixIcon: Icon(
Icons.phone,
color: Colors.black,
),
hintText: 'Enter Phone Number',
fillColor: Colors.white,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
focusColor: Colors.blue,
),
onChanged: (value){
phoneNumber = value;
},
),
),
SizedBox(
height: 40,
),
Row(
children: <Widget>[
Text(
'Select Vehicle:',
style: TextStyle(
color: Colors.blue,
fontSize: 15,
),),
SizedBox(
width: 20,
),
Center(
child: DropdownButton<String>(
value: uDropdownvalue,
elevation: 16,
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_downward,
color: Colors.black,
),
style: TextStyle(
color: Colors.black,
fontSize: 15,
),
underline: Container(
height: 1,
color: Colors.black,
),
items: vehicles.map<DropdownMenuItem<String>>((String vehicle) {
return DropdownMenuItem<String>(
value: vehicle,
child: Text(vehicle),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
uDropdownvalue = newValue;
});
},
),
),
],
),
SizedBox(
height: 20,
),
Text(
'Add Description:',
style: TextStyle(
color: Colors.blue,
fontSize: 18,
),
),
Expanded(
child: Container(
child: TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
)
),
),
style: TextStyle(
color: Colors.black,
),
onChanged: (value){
description=value;
},
),
),
),
Row(
children: [
Expanded(
child: buildGestureDetector(context,_image1),
),
Expanded(
child: buildGestureDetector(context,_image2),
),
Expanded(
child: buildGestureDetector(context,_image3),
),
],
),
Roundedbutton(
color: Colors.yellow,
title: 'Upload vehicle',
onPressed: () async {
setState(() {
showSpinner = true;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Details uploaded successfully')),
);
_firestore.collection('Uploading Vehicle Details').add({
'City': uCity,
'Vehicle': uDropdownvalue,
'Description' : description,
'Phone.No#' : phoneNumber,
});
Navigator.pushNamed(context, HomeScreen.id);
},
),
],
),
),
),
),
),
);
}
GestureDetector buildGestureDetector(BuildContext context, File _image) {
//GestureDetector({#required this._image});
//File _image;
return GestureDetector(
onTap: () {
_showPicker(context, 'A');
},
child: CircleAvatar(
radius: 53,
backgroundColor: Colors.black,
child: _image != null
? ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image.file(
_image,
width: 100,
height: 100,
fit: BoxFit.fitHeight,
),
)
: Container(
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(50)),
width: 100,
height: 100,
child: Icon(
Icons.camera_alt,
color: Colors.grey[800],
),
),
),
);
}
}
And below is the code for the user who wants to book vehicle in his city. So it should search in firebase if the required details are present in the firebase or not. If yes it should retrieve the details from the firebase and show it to the person who's looking for it.
import 'package:flash_chat/constants.dart';
import 'package:flash_chat/constraints/rounded_button.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:flash_chat/screens/uploading_vehicle.dart';
class Booking extends StatefulWidget {
static const id = 'booking';
#override
_BookingState createState() => _BookingState();
}
class _BookingState extends State<Booking> {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
final UploadingVehicle uv = new UploadingVehicle();
bool showSpinner = false;
String city;
String dropdownvalue = 'Hiace';
var vehicles = ['Car','Suzuki Bolan','Hiace'];
Object get uCity => null;
Object get uDropdownvalue => null;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black, //change your color here
),
title: Text('Book vehicle'.toUpperCase(),
style: TextStyle(color: Colors.black)),
backgroundColor: Colors.yellowAccent.shade700,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back)),
actions: [
Icon(Icons.person),
],
),
body: SafeArea(
child: Container(
child: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
SizedBox(
height: 40,
),
Material(
elevation: 18,
shadowColor: Colors.black,
child: TextField(
style: TextStyle(
color: Colors.black,
),
decoration: kRegisterTextFieldDecoration.copyWith(
hintText: 'Enter City',
fillColor: Colors.white,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
onChanged: (value){
city=value;
},
),
),
SizedBox(
height: 40,
),
Row(
children: <Widget>[
Text(
'Select Vehicle:',
style: TextStyle(
color: Colors.blue,
fontSize: 15,
),),
SizedBox(
width: 20,
),
Center(
child: DropdownButton<String>(
value: dropdownvalue,
elevation: 16,
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_downward,
color: Colors.black,
),
style: TextStyle(
color: Colors.black,
fontSize: 15,
),
underline: Container(
height: 1,
color: Colors.black,
),
items: vehicles.map<DropdownMenuItem<String>>((String vehicle) {
return DropdownMenuItem<String>(
value: vehicle,
child: Text(vehicle),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
dropdownvalue = newValue;
});
},
),
),
],
),
Roundedbutton(
color: Colors.yellow,
title: 'Search for vehicle',
onPressed: () async {
setState(() {
showSpinner = true;
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Searched')),
);
_firestore.collection('Booking Details').add({
'City': city,
'Vehicle': dropdownvalue,
});
Navigator.pushNamed(context, Booking.id);
},
),
Container(
color: Colors.white,
child: Text('Details matched',
style: TextStyle(
color: Colors.black,
fontSize: 30,
),
)
: Text(
'Details not matched',
style: TextStyle(
color: Colors.black,
fontSize: 30,
),),
),
],
),
),
),
),
),
);
}
}
How am I supposed to do this?
As far as I can tell from the massive amount of code you shared, this is the code that adds the vehicle details to the database:
_firestore.collection('Uploading Vehicle Details').add({
'City': uCity,
'Vehicle': uDropdownvalue,
'Description' : description,
'Phone.No#' : phoneNumber,
});
If you want to search that information, you can use a query such as this one:
_firestore.collection('Uploading Vehicle Details')
.where('City', isEqualTo: 'San Francisco')
.where('Vehicle', isEqualTo: 'Toyota RAV4')
.get()
.then(...);
If you want to show this in the UI, you'll want to use snapshots instead of get and wrap it in a StreamBuilder as shown in the documentation on listening to realtime changes.
my signup.dart file:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class SignUp extends StatefulWidget {
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final _formKey = GlobalKey<FormState>();
TextEditingController _emailTextController = TextEditingController();
TextEditingController _passwordTextController = TextEditingController();
TextEditingController _nameTextController = TextEditingController();
TextEditingController _confirmPasswordTextController =
TextEditingController();
String gender;
String groupValue = "Erkek";
bool loading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Image.asset(
'images/backg.jpg',
fit: BoxFit.fill,
width: double.infinity,
height: double.infinity,
),
Container(
color: Colors.black.withOpacity(0.4),
width: double.infinity,
height: double.infinity,
),
Padding(
padding: const EdgeInsets.only(top: 200.0),
child: Center(
child: Form(
key: _formKey,
child: ListView(
children: <Widget>[
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _passwordTextController,
decoration: InputDecoration(
hintText: "Ad Soyad",
icon: Icon(Icons.person),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
return "İsim boşluğu doldurulmalıdır.";
}
return null;
},
// ignore: missing_return
),
trailing: Icon(Icons.remove_red_eye),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: TextFormField(
controller: _emailTextController,
decoration: InputDecoration(
hintText: "Email",
icon: Icon(Icons.email),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
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 "Lütfen geçerli bir mail adresi giriniz.";
else
return null;
}
}),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: new Container(
color: Colors.white.withOpacity(0.4),
child: Row(
children: <Widget>[
Expanded(
child: ListTile(
title: Text(
"Erkek",
textAlign: TextAlign.end ,
style: TextStyle(color: Colors.white),
),
trailing: Radio(value: "Erkek", groupValue: groupValue, onChanged: (e)=>valueChanged(e)),
)),
Expanded(
child: ListTile(
title: Text(
"Kadın",
textAlign: TextAlign.end ,
style: TextStyle(color: Colors.white),
),
trailing: Radio(value: "Kadın", groupValue: groupValue, onChanged: (e)=>valueChanged(e)),
)),
],
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _passwordTextController,
obscureText: true,
decoration: InputDecoration(
hintText: "Şifre",
icon: Icon(Icons.lock_outline),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
return "Şifre boşluğu doldurulmalıdır.";
} else if (value.length < 6) {
return "Şifre 6 haneden uzun olmalı!";
}
return null;
},
// ignore: missing_return
),
trailing : IconButton(icon: Icon(Icons.remove_red_eye), onPressed: (){})
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.white.withOpacity(0.4),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title : TextFormField(
controller: _confirmPasswordTextController,
obscureText: true,
decoration: InputDecoration(
hintText: "Şifreyi Doğrula",
icon: Icon(Icons.lock_outline),
border: InputBorder.none
),
// ignore: missing_return
validator: (value) {
if (value.isEmpty) {
return "Şifre boşluğu doldurulmalıdır.";
} else if (value.length < 6) {
return "Şifre 6 haneden uzun olmalı!";
}else if (_passwordTextController != value){
return "Şifreler uyuşmuyor.";
}
return null;
},
// ignore: missing_return
),
trailing : IconButton(icon: Icon(Icons.remove_red_eye), onPressed: (){}),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: Colors.red.withOpacity(0.8),
elevation: 0.0,
child: MaterialButton(
onPressed: () {
validateForm();
},
minWidth: MediaQuery.of(context).size.width,
child: Text(
"Kayıt Ol",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 15.0),
),
)),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Text(
"Giriş Yap",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red),
))),
],
)),
),
),
Visibility(
visible: loading ?? true,
child: Center(
child: Container(
alignment: Alignment.center,
color: Colors.white.withOpacity(0.9),
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
),
))
],
),
);
}
valueChanged(e) {
setState(() {
if (e == "Erkek") {
groupValue = e;
gender = e;
} else if (e == "Kadın") {
groupValue = e;
gender = e;
}
});
}
void validateForm() async{
FormState formState = _formKey.currentState;
if(formState.validate()){
User user = await firebaseAuth.currentUser;
if(user == null){
firebaseAuth.createUserWithEmailAndPassword(email: _emailTextController, password: _passwordTextController).then((user) => {
});
}
}
}
}
My Showing errors.
Performing hot reload...
Syncing files to device sdk gphone x86...
lib/pages/signup.dart:276:60: Error: The argument type 'TextEditingController' can't be assigned to the parameter type 'String'.
'TextEditingController' is from 'package:flutter/src/widgets/editable_text.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/editable_text.dart').
firebaseAuth.createUserWithEmailAndPassword(email: _emailTextController, password: _passwordTextController).then((user) => {
^
lib/pages/signup.dart:276:92: Error: The argument type 'TextEditingController' can't be assigned to the parameter type 'String'.
'TextEditingController' is from 'package:flutter/src/widgets/editable_text.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/editable_text.dart').
firebaseAuth.createUserWithEmailAndPassword(email: _emailTextController, password: _passwordTextController).then((user) => {
^
==========NEW ERRORRR=================
void validateForm() async {
FormState formState = _formKey.currentState;
if (formState.validate()) {
User user = await firebaseAuth.currentUser;
if (user == null) {
firebaseAuth
.createUserWithEmailAndPassword(
email: _emailTextController.text,
password: _passwordTextController.text)
.then((user) => {
_userServices.createUser(
{
"username": _nameTextController.text,
"email": user.email
}
)
});
}
}
}
}
Use _emailTextController.text instead of just _emailTextController.
I'm new to flutter and I have created an application with login/signup screens and connected my app to fire base, it's successfully connected but when signup or login it keeps spinning. However, I can see in firebase user is added but it doesn't get access to application home screen.
Here is my dart code for sign up:
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_login_screen/model/User.dart';
import 'package:flutter_login_screen/ui/home/HomeScreen.dart';
import 'package:flutter_login_screen/ui/services/Authenticate.dart';
import 'package:flutter_login_screen/ui/utils/helper.dart';
import 'package:image_picker/image_picker.dart';
import '../../constants.dart' as Constants;
import '../../constants.dart';
import '../../main.dart';
File _image;
class SignUpScreen extends StatefulWidget {
#override
State createState() => _SignUpState();
}
class _SignUpState extends State<SignUpScreen> {
TextEditingController _passwordController = new TextEditingController();
GlobalKey<FormState> _key = new GlobalKey();
bool _validate = false;
String firstName, lastName, email, mobile, 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,
autovalidate: _validate,
child: formUI(),
),
),
),
);
}
Future<void> retrieveLostData() async {
final LostDataResponse response = await ImagePicker.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
_image = response.file;
});
}
}
_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);
var image =
await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
});
},
),
CupertinoActionSheetAction(
child: Text("Take a picture"),
isDestructiveAction: false,
onPressed: () async {
Navigator.pop(context);
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
});
},
)
],
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: Colors.deepOrange[900],
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_ACCENT),
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: (String val) {
firstName = val;
},
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'First Name',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Colors.deepOrange[900],
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(
validator: validateName,
onSaved: (String val) {
lastName = val;
},
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'Last Name',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Colors.deepOrange[900],
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.phone,
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
validator: validateMobile,
onSaved: (String val) {
mobile = val;
},
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(
vertical: 8, horizontal: 16),
fillColor: Colors.white,
hintText: 'Mobile Number',
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0),
borderSide: BorderSide(
color: Colors.deepOrange[900],
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,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
validator: validateEmail,
onSaved: (String 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: Colors.deepOrange[900],
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,
onFieldSubmitted: (_) => FocusScope.of(context).nextFocus(),
controller: _passwordController,
validator: validatePassword,
onSaved: (String val) {
password = val;
},
style: TextStyle(height: 0.8, fontSize: 18.0),
cursorColor: Colors.deepOrange[900],
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: Colors.deepOrange[900],
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: (_) {
_sendToServer();
},
obscureText: true,
validator: (val) =>
validateConfirmPassword(_passwordController.text, val),
onSaved: (String val) {
confirmPassword = val;
},
style: TextStyle(height: 0.8, fontSize: 18.0),
cursorColor: Colors.deepOrange[900],
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: Colors.deepOrange[900], 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: RaisedButton(
color: Color(Constants.FACEBOOK_BUTTON_COLOR),
child: Text(
'Sign Up',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
textColor: Colors.white,
splashColor: Color(Constants.FACEBOOK_BUTTON_COLOR),
onPressed: _sendToServer,
padding: EdgeInsets.only(top: 12, bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
side: BorderSide(
color: Color(Constants.FACEBOOK_BUTTON_COLOR))),
),
),
),
],
);
}
_sendToServer() async {
if (_key.currentState.validate()) {
_key.currentState.save();
showProgress(context, 'Creating new account...', false);
var profilePicUrl = '';
try {
AuthResult result = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
if (_image != null) {
updateProgress('Uploading image...');
profilePicUrl = await FireStoreUtils()
.uploadUserImageToFireStorage(_image, result.user.uid);
}
User user = User(
email: email,
firstName: firstName,
phoneNumber: mobile,
userID: result.user.uid,
active: true,
lastName: lastName,
settings: Settings(allowPushNotifications: true),
profilePictureURL: profilePicUrl);
await FireStoreUtils.firestore
.collection(Constants.USERS)
.document(result.user.uid)
.setData(user.toJson());
hideProgress();
MyAppState.currentUser = user;
pushAndRemoveUntil(context, HomeScreen(user: user), false);
} catch (error) {
hideProgress();
(error as PlatformException).code != 'ERROR_EMAIL_ALREADY_IN_USE'
? showAlertDialog(context, 'Failed', 'Couldn\'t sign up')
: showAlertDialog(context, 'Failed',
'Email already in use. Please pick another email address');
print(error.toString());
}
} else {
print('false');
setState(() {
_validate = true;
});
}
}
#override
void dispose() {
_passwordController.dispose();
_image = null;
super.dispose();
}
}
helper:
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';
String validateName(String value) {
String pattern = r'(^[a-zA-Z ]*$)';
RegExp regExp = new RegExp(pattern);
if (value.length == 0) {
return "Name is required";
} else if (!regExp.hasMatch(value)) {
return "Name must be a-z and A-Z";
}
return null;
}
String validateMobile(String value) {
String pattern = r'(^[0-9]*$)';
RegExp regExp = new RegExp(pattern);
if (value.length == 0) {
return "Mobile phone number is required";
} else if (!regExp.hasMatch(value)) {
return "Mobile phone number must contain only digits";
}
return null;
}
String validatePassword(String value) {
if (value.length < 6)
return 'Password must be more than 5 charaters';
else
return null;
}
String validateEmail(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 'Enter Valid Email';
else
return null;
}
String validateConfirmPassword(String password, String confirmPassword) {
print("$password $confirmPassword");
if (password != confirmPassword) {
return 'Password doesn\'t match';
} else if (confirmPassword.length == 0) {
return 'Confirm password is required';
} else {
return null;
}
}
//helper method to show progress
ProgressDialog progressDialog;
showProgress(BuildContext context, String message, bool isDismissible) async {
progressDialog = new ProgressDialog(context,
type: ProgressDialogType.Normal, isDismissible: isDismissible);
progressDialog.style(
message: message,
borderRadius: 10.0,
backgroundColor: Colors.deepOrange[900],
progressWidget: Container(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(
backgroundColor: Colors.white,
)),
elevation: 10.0,
insetAnimCurve: Curves.easeInOut,
messageTextStyle: TextStyle(
color: Colors.white, fontSize: 19.0, fontWeight: FontWeight.w600));
await progressDialog.show();
}
updateProgress(String message) {
progressDialog.update(message: message);
}
hideProgress() async {
await progressDialog.hide();
}
//helper method to show alert dialog
showAlertDialog(BuildContext context, String title, String content) {
// set up the AlertDialog
Widget okButton = FlatButton(
child: Text("OK"),
onPressed: () {
Navigator.pop(context);
},
);
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(content),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
pushReplacement(BuildContext context, Widget destination) {
Navigator.of(context).pushReplacement(
new MaterialPageRoute(builder: (context) => destination));
}
push(BuildContext context, Widget destination) {
Navigator.of(context)
.push(new MaterialPageRoute(builder: (context) => destination));
}
pushAndRemoveUntil(BuildContext context, Widget destination, bool predict) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => destination),
(Route<dynamic> route) => predict);
}
Widget displayCircleImage(String picUrl, double size, hasBorder) =>
CachedNetworkImage(
imageBuilder: (context, imageProvider) =>
_getCircularImageProvider(imageProvider, size, false),
imageUrl: picUrl,
placeholder: (context, url) =>
_getPlaceholderOrErrorImage(size, hasBorder),
errorWidget: (context, url, error) =>
_getPlaceholderOrErrorImage(size, hasBorder));
Widget _getPlaceholderOrErrorImage(double size, hasBorder) => Container(
width: size,
height: size,
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
borderRadius: new BorderRadius.all(new Radius.circular(size / 2)),
border: new Border.all(
color: Colors.white,
width: hasBorder ? 2.0 : 0.0,
),
),
child: ClipOval(
child: Image.asset(
'assets/images/placeholder.jpg',
fit: BoxFit.cover,
height: size,
width: size,
)),
);
Widget _getCircularImageProvider(
ImageProvider provider, double size, bool hasBorder) {
return Container(
width: size,
height: size,
decoration: BoxDecoration(
color: const Color(0xff7c94b6),
borderRadius: new BorderRadius.all(new Radius.circular(size / 2)),
border: new Border.all(
color: Colors.white,
width: hasBorder ? 2.0 : 0.0,
),
),
child: ClipOval(
child: FadeInImage(
fit: BoxFit.cover,
placeholder: Image.asset(
'assets/images/placeholder.jpg',
fit: BoxFit.cover,
height: size,
width: size,
).image,
image: provider)),
);
}
Error: Could not find the correct Provider above this SignUp Widget
To fix, please:
Ensure the Provider is an ancestor to this SignUp
Widget
Provide types to Provider
Provide types to Consumer
Provide types to Provider.of()
Ensure the correct context is being used.
class SignUp extends StatefulWidget {
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final _formKey = GlobalKey<FormState>();
final _key = GlobalKey<ScaffoldState>();
TextEditingController _email = TextEditingController();
TextEditingController _password = TextEditingController();
TextEditingController _name = TextEditingController();
bool hidePass = true;
#override
Widget build(BuildContext context) {
final user = Provider.of<UserProvider>(context);
return Scaffold(
key: _key,
body: user.status == Status.Authenticating ? Loading() : Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left:20, right:20.0, top: 80),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.grey[350],
blurRadius:
20.0, // has the effect of softening the shadow
)
],
),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
alignment: Alignment.topCenter,
child: Image.asset(
'images/cart.png',
width: 120.0,
// height: 240.0,
)),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(10.0),
color: Colors.grey.withOpacity(0.2),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _name,
decoration: InputDecoration(
hintText: "Full name",
icon: Icon(Icons.person_outline),
border: InputBorder.none),
validator: (value) {
if (value.isEmpty) {
return "The name field cannot be empty";
}
return null;
},
),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(10.0),
color: Colors.grey.withOpacity(0.2),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _email,
decoration: InputDecoration(
hintText: "Email",
icon: Icon(Icons.alternate_email),
border: InputBorder.none),
validator: (value) {
if (value.isEmpty) {
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 'Please make sure your email address is valid';
else
return null;
}
return null;
},
),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(10.0),
color: Colors.grey.withOpacity(0.2),
elevation: 0.0,
child: Padding(
padding: const EdgeInsets.only(left: 12.0),
child: ListTile(
title: TextFormField(
controller: _password,
obscureText: hidePass,
decoration: InputDecoration(
hintText: "Password",
icon: Icon(Icons.lock_outline),
border: InputBorder.none),
validator: (value) {
if (value.isEmpty) {
return "The password field cannot be empty";
} else if (value.length < 6) {
return "the password has to be at least 6 characters long";
}
return null;
},
),
trailing: IconButton(
icon: Icon(Icons.remove_red_eye),
onPressed: () {
setState(() {
hidePass = false;
});
}),
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
color: deepOrange,
elevation: 0.0,
child: MaterialButton(
onPressed: () async{
if(_formKey.currentState.validate()){
if(!await user.signUp(_name.text ,_email.text, _password.text))
_key.currentState.showSnackBar(SnackBar(content: Text("Sign up failed")));
}
},
minWidth: MediaQuery.of(context).size.width,
child: Text(
"Sign up",
textAlign: TextAlign.center,
style: TextStyle(
color: white,
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
)),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {
Navigator.pop(context);
},
child: Text(
"I already have an account",
textAlign: TextAlign.center,
style: TextStyle(color: deepOrange, fontSize: 16),
))),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Or sign up with", style: TextStyle(fontSize: 18,color: Colors.grey),),
),
Padding(
padding:
const EdgeInsets.fromLTRB(14.0, 8.0, 14.0, 8.0),
child: Material(
child: MaterialButton(
onPressed: () async{
if(!await user.signUpWithGoogle())
_key.currentState.showSnackBar(SnackBar(content: Text("Sign in failed")));
},
child: Image.asset("assets/google-48.png", width: 30,)
)),
),
],
),
),
],
)),
),
),
],
),
);
}
}
keep getting error what am I doing wrong
I am facing a anonymus closure error in flutter while signing in a user. It worked a few days before but now its not working, I dont no why. So please help and thanks in advance..Whenever i fill the details and tap on the signin button it throws the below error---
E/flutter ( 2914): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter ( 2914): FormatException: Unexpected end of input (at character 1)
E/flutter ( 2914):
E/flutter ( 2914): ^
E/flutter ( 2914):
E/flutter ( 2914): #0 _ChunkedJsonParser.fail (dart:convert/runtime/libconvert_patch.dart:1358:5)
E/flutter ( 2914): #1 _ChunkedJsonParser.close (dart:convert/runtime/libconvert_patch.dart:511:7)
E/flutter ( 2914): #2 _parseJson (dart:convert/runtime/libconvert_patch.dart:30:10)
E/flutter ( 2914): #3 JsonDecoder.convert (dart:convert/json.dart:540:36)
E/flutter ( 2914): #4 JsonCodec.decode (dart:convert/json.dart:167:41)
E/flutter ( 2914): #5 _SignInState._login.<anonymous closure> (package:restaurant_app/signin.dart:81:23)
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:restaurant_app/globalVar.dart';
import 'package:restaurant_app/homescreen.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:restaurant_app/signup.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_html_view/html_parser.dart';
class SignIn extends StatefulWidget {
#override
_SignInState createState() => _SignInState();
}
class _SignInState extends State<SignIn> with SingleTickerProviderStateMixin
{
TabController controller;
TextEditingController _email = new TextEditingController();
TextEditingController _password = new TextEditingController();
bool loading;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>
();
#override
void initState() {
// TODO: implement initState
super.initState();
controller = new TabController(length: 2, vsync: this);
loading = false;
_email = new TextEditingController(text: "rajeshvishnani");
_password = new TextEditingController(text: "Rajesh#MaaKiRasoi");
}
#override
void dispose() {
// TODO: implement dispose
super.dispose();
controller.dispose();
setState(() {
loading = false;
});
_email.dispose();
_password.dispose();
}
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
bool _autoValidate = false;
Future _writer(String username, String password, String token) async {
final storage = new FlutterSecureStorage();
await storage.write(key: authTokenKeys, value: token);
print(await storage.read(key: authTokenKeys));
await storage.write(key: nameKeys, value: username);
print(await storage.read(key: nameKeys));
await storage.write(key: passwordKeys, value: password);
}
static final String authTokenKeys = 'auth_token';
static final String nameKeys = 'username';
static final String passwordKeys = 'password';
_login(username, password) async {
setState(() {
loading = true;
});
var body = json.encode({
"username": username,
"password": password,
});
Map<String, String> headers = {
'Content-type': 'application/json',
'Accept': 'application/json',
};
await http
.post("${GlobalVar.Ip}/wp-json/jwt-auth/v1/token",
body: body, headers: headers)
.then((response) {
var body = json.decode(response.body);
if (response.statusCode == 200) {
// TODO: you need to store body['token'] to use in some authentication
loading = false;
_writer(_email.text, _password.text, body['token']);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext ctx) => HomePage()));
} else {
// TODO: alert message
final snackBar = SnackBar(
content: Text(body['message']),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
setState(() {
loading = false;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomPadding: false,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/art.png'),
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
Colors.white12.withOpacity(0.2), BlendMode.dstATop),
),
),
child: ListView(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Align(
alignment: Alignment.topCenter,
child: CircleAvatar(
backgroundColor: Colors.grey,
radius: 55.0,
backgroundImage: AssetImage('images/logo.png'),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 300,
child: new Center(
child: new Container(
height: 10.0,
color: Colors.black12,
),
),
),
Row(
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width / 4,
),
Chip(
label: Text(
"SIGN IN",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
backgroundColor: Color(0xFFD1A155),
),
SizedBox(
width: MediaQuery.of(context).size.width / 35,
child: Container(
width: MediaQuery.of(context).size.height / 12,
height: 2.0,
color: Colors.white,
),
),
Chip(
label: Text(
"SIGN UP",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
backgroundColor: Colors.black87,
),
],
)
],
),
SizedBox(
height: MediaQuery.of(context).size.height / 35,
),
Align(
alignment: Alignment.center,
child: Text(
"Welcome back!",
style: TextStyle(
fontSize: 20.0,
color: Color(0xFFD1A155),
),
)),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Form(
key: _formKey,
autovalidate: _autoValidate,
child: Column(
children: <Widget>[
Theme(
data: ThemeData(
hintColor: Colors.black26,
primaryColor: Color(0xFFD1A155),
),
child: Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
//validator: _email.text.isEmpty?:null,
controller: _email,
decoration: InputDecoration(
border:
OutlineInputBorder(borderSide: BorderSide()),
prefixIcon: Icon(
Icons.email,
color: Color(0xFFD1A155),
),
hintText: 'Email Address',
hintStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400)),
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 45,
),
Theme(
data: ThemeData(
primaryColor: Color(0xFFD1A155),
hintColor: Colors.black26),
child: Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
controller: _password,
decoration: InputDecoration(
border:
OutlineInputBorder(borderSide: BorderSide()),
prefixIcon: Icon(
Icons.lock,
color: Color(0xFFD1A155),
),
hintText: 'Password',
hintStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400)),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 15.0, left: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
ActionChip(
onPressed: () {},
avatar: Checkbox(
value: false,
onChanged: (bool z) {
print(z);
},
activeColor: Color(0xFFD1A155),
),
label: Text("Remember Me"),
backgroundColor: Colors.transparent,
),
],
),
Text(
"Forgot Password?",
style: TextStyle(
color: Color(0xFFD1A155),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: InkWell(
onTap: () {
_login(_email.text, _password.text);
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => HomePage()));
},
child: loading
? CircularProgressIndicator()
: Container(
height: MediaQuery.of(context).size.height / 13,
//width: MediaQuery.of(context).size.height / 1.8,
decoration: BoxDecoration(
color: Color(0xFFD1A155),
borderRadius: BorderRadius.circular(5.0),
),
child: Center(
child: Text(
"LOGIN",
style: TextStyle(
color: Colors.white, fontSize: 18.0),
),
),
),
),
)
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 15,
),
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
height: 2.0,
child: new Center(
child: new Container(
height: 10.0,
color: Colors.black12,
),
),
),
Container(
height: MediaQuery.of(context).size.height / 18,
width: MediaQuery.of(context).size.height / 11,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(23.0),
color: Colors.white,
border: Border.all(color: Colors.black12)),
child: Center(
child: Text(
"OR",
style: TextStyle(fontSize: 18.0),
)),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: Row(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 2.2,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white,
border: Border.all(color: Colors.black12)),
child: Row(
children: <Widget>[
SizedBox(
width: 18.0,
),
Icon(Icons.tag_faces),
SizedBox(
width: 10.0,
),
Text(
"Facebook",
style: TextStyle(fontSize: 22.0, color: Colors.blue),
),
],
),
),
SizedBox(
width: MediaQuery.of(context).size.width / 40,
),
Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 2.3,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white,
border: Border.all(color: Colors.black12)),
child: Row(
children: <Widget>[
SizedBox(
width: 18.0,
),
Icon(Icons.tag_faces),
SizedBox(
width: 10.0,
),
Text(
"Google+",
style: TextStyle(fontSize: 22.0, color: Colors.red),
),
],
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 20,
),
Align(
alignment: Alignment.center,
child: InkWell(
onTap: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => SignUp())),
child: RichText(
text: TextSpan(
text: "Don't have an account?",
style: TextStyle(fontSize: 20.0, color: Colors.black87),
children: <TextSpan>[
TextSpan(
text: ' Sign up',
style: TextStyle(
color: Color(0xFFD1A155),
fontWeight: FontWeight.bold)),
])),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
],
),
),
);
}
}
I also have similar type of error, Be make sure that the argument of .decode method shouldn't be empty object. Instead of using this line:
var body = json.decode(response.body);
Try
if(response.body.isNotEmpty) {
json.decode(response.body);
}
Do try this, hope it will work for you.
Print your body and double check you aren't trying to decode an array rather than on object.
I had similar type of problem, i tried everything but eventually the problem was that I was using http intead of using https even though the apis was in https, i forgot to add s at in http.
After changing to https from http the error was gone.
check your backend it return null object in the response body