Related
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 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.
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)),
);
}
I want to get the value of (profile.imgUrl) from Firestore but I get error:
The getter 'imgUrl' was called on null.
Receiver: null
Tried calling: imgUrl
Although the user is signed in and I can get the data in the home page but when I navigate to Account page it gives me this error.
class Account extends StatelessWidget {
final Profile profile;
Account({this.profile});
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
print(profile.imgUrl);
return StreamProvider<List<Profile>>.value(
value: DatabaseService().profiles,
child: Scaffold(
body: Stack(
children: <Widget>[
ClipPath(
child: Container(
color: Colors.green.withOpacity(0.8),
),
clipper: getClipper(),
),
Positioned(
width: 400,
top: MediaQuery.of(context).size.height / 5,
child: Column(
children: <Widget>[
Container(
width: 150.0,
height: 150.0,
decoration: BoxDecoration(
color: Colors.green,
image: DecorationImage(
image: NetworkImage(profile.imgUrl),
fit: BoxFit.cover),
borderRadius: BorderRadius.all(Radius.circular(75.0)),
boxShadow: [
BoxShadow(blurRadius: 7.0, color: Colors.black)
]),
),
SizedBox(
height: 90.0,
),
Text(
'Alex Ali',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
fontFamily: 'Montserrat',
letterSpacing: 1.5),
),
SizedBox(
height: 15.0,
),
Text(
'New Seller',
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 17.0,
color: Colors.green),
),
SizedBox(
height: 25,
),
Container(
height: 30.0,
width: 95.0,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.greenAccent,
color: Colors.green,
elevation: 7.0,
child: GestureDetector(
onTap: () {
print(profile.imgUrl);
},
child: Center(
child: Text(
'Edit Name',
style: TextStyle(color: Colors.white),
),
),
),
),
),
SizedBox(
height: 25,
),
Container(
height: 30.0,
width: 95.0,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.redAccent,
color: Colors.red,
elevation: 7.0,
child: GestureDetector(
onTap: () async {
await _auth.signOut();
},
child: Center(
child: Text(
'Log out',
style: TextStyle(color: Colors.white),
),
),
),
),
)
],
),
)
],
)
),
);
}
}
class getClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
var path = new Path();
path.lineTo(0.0, size.height / 1.9);
path.lineTo(size.width + 125, 0.0);
path.close();
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
and that is Home page code:
class Home extends StatefulWidget {
#override
_Home createState() => _Home();
}
class _Home extends State<Home> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return StreamProvider<List<Profile>>.value(
value: DatabaseService().profiles,
child: Scaffold(
body: SafeArea(
child: ListView(
padding: EdgeInsets.symmetric(vertical: 30.0),
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20.0, right: 120.0),
child: Text(
"What would you like to find?",
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
SizedBox(height: 20.0),
SizedBox(
height: 20.0,
),
SizedBox(height: 500, child: ProfileList()),
],
),
),
),
);
}
}
Here is the code that opens Account page through BottomNavigationBar:
class Wrapper extends StatefulWidget {
#override
_WrapperState createState() => _WrapperState();
}
class _WrapperState extends State<Wrapper> {
int _currentTab = 0;
final _page = [
Home(),
Search(),
Account(),
];
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print(user);
if (user == null) {
return Authenticate();
} else {
return Scaffold(
body: _page[_currentTab],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentTab,
onTap: (int value) {
setState(() {
_currentTab = value;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
size: 30.0,
),
title: SizedBox.shrink()),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
size: 30.0,
),
title: SizedBox.shrink()),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
size: 30.0,
),
title: SizedBox.shrink(),
)
]),
);
}
}
}
You need to pass a Profile as a parameter when Account is created.
That should be done dynamically, so you can't use a fixed list.
Instead of doing this:
final _page = [
Home(),
Search(),
Account(),
];
Scaffold(
body: _page[_currentTab],
// ...
)
You should do something like this:
Widget _getPage(int pos, user User) {
switch (pos) {
case 0:
return Home();
case 1:
return Search();
case 2:
return Account(user.profile); // Assuming profile is a member of user
default:
return Container();
}
}
Scaffold(
body: _getPage(_currentTab, user),
// ...
)
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