I am getting error on red screen right after i run my app. My first screen is login screen. I want to simply register the user and login the user. but when i use the getUsers() or getLogin() I get the above error. I am fed up of this error. Searched everywhere but m not able to find any working solutions. Please can u please write the code which i need to add. Please help me.
UserLogin.dart
import 'dart:ui';
import 'package:customer/models/registerUser.dart';
import 'package:customer/screens/UserRegistration.dart';
import 'package:customer/screens/people_list.dart';
import 'package:customer/services/db_service.dart';
import 'package:customer/utils/form_helper.dart';
import 'package:flutter/material.dart';
import 'ForgotPassword.dart';
class UserLogin extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return UserLoginState();
}
}
class UserLoginState extends State<UserLogin>{
final reguser = RegisterUser();
String name,_password,_email;
var _formKey=GlobalKey<FormState>();
RegisterUser model;
DBService dbService;
var _minimumPadding = 5.0;
TextEditingController usernameController=TextEditingController();
TextEditingController passwordController=TextEditingController();
bool isHiddenPassword=true;
final scaffoldKey = new GlobalKey<ScaffoldState>();
void _showSnackBar(String text) {
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(text),
));
}
void _togglePasswordView() {
setState(() {
isHiddenPassword = !isHiddenPassword;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Customer Tracking System'),),
body:_fetchData(),
);
}
Widget _fetchData(){
return FutureBuilder<List<RegisterUser>>(
future: dbService.getUsers(),
builder:
(BuildContext context, AsyncSnapshot<List<RegisterUser>> userDetails) {
if (userDetails.hasData) {
return _loginUI(userDetails.data);
}
return CircularProgressIndicator();
},
);
}
Widget _loginUI(List<RegisterUser> userDetails){
TextStyle textStyle = Theme.of(context).textTheme.title;
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
Form(
key: _formKey,
child: Container(
child: Padding(
padding: EdgeInsets.all(_minimumPadding * 2),
child: ListView
(
children: <Widget>[
Text("Login".toUpperCase(),
style: TextStyle(
fontSize: 40.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center),
SizedBox(height: height * 0.08,),
Divider(),
Padding(
padding: EdgeInsets.only(
top: _minimumPadding * 3,
bottom: _minimumPadding),
child: TextFormField(
controller: usernameController,
style: textStyle,
validator: (String value) {
if (value.isEmpty) {
return 'Please Enter Name';
}
return null;
},
onSaved: (String value) {
_email = value;
},
decoration: InputDecoration(
// filled: true,
//fillColor: Colors.white,
prefixIcon: Icon(Icons.person),
labelText: 'Username',
hintText: 'Username',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0)
)
)
)),
Padding(
padding: EdgeInsets.only(
top: _minimumPadding * 3,
bottom: _minimumPadding),
child: TextFormField(
style: textStyle,
obscureText: isHiddenPassword,
controller: passwordController,
validator: (String value) {
if (value.isEmpty) {
return 'Please Enter Name';
}
return null;
},
onSaved: (String value) {
_password = value;
},
decoration: InputDecoration(
prefixIcon: Icon(Icons.lock),
suffixIcon: InkWell(
onTap: _togglePasswordView,
child: Icon(Icons.visibility)),
labelText: 'Password',
hintText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25.0)
)
)
)
),
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ForgotPassword()));
},
child: Text(
"Forgot Password ?",
style: TextStyle(
fontSize: 18,
color: Colors.purpleAccent,
//fontWeight: FontWeight.bold,
letterSpacing: 1.7),
textAlign: TextAlign.right,
),
),
SizedBox(
height: height * 0.08,
),
GestureDetector(
onTap: () {
_submit();
},
child: Container(
padding:
EdgeInsets.symmetric(horizontal: 26, vertical: 20),
decoration: BoxDecoration(
//gradient: new LinearGradient(
//colors: [Colors.purple, Colors.purpleAccent]),
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
blurRadius: 4,
//color: Colors.purpleAccent,
offset: Offset(2, 2))
]),
child: Text(
"Login".toUpperCase(),
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1.7),
textAlign: TextAlign.center,
),
),
),
SizedBox(
height: height * 0.05,
),
SizedBox(
height: height * 0.05,
),
Row(
children: <Widget>[
Expanded(
child: Text("Not yet registered?",
style: TextStyle(
fontSize: 25.0)
)
),
GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => UserRegistration()));
},
child: Center(
child: Container(
padding:
EdgeInsets.symmetric(
horizontal: 26, vertical: 10),
decoration: BoxDecoration(
//gradient: new LinearGradient(
// colors: [Colors.purple, Colors.purpleAccent]),
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
blurRadius: 4,
//color:,
offset: Offset(2, 2))
]),
child: Text(
"Register".toUpperCase(),
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
letterSpacing: 1.7),
textAlign: TextAlign.center,
),
),
),
)
],
),
],
)),
),
);
}
bool validateAndSave() {
final form = _formKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
void _submit(){
final form = _formKey.currentState;
var res;
if (validateAndSave()) {
setState(() {
//getLogin(_email, _password);
res=dbService.getLogin(_email, _password).then((value) {
if(res!=0){
FormHelper.showMessage(
context,
"Login",
"Login Successfull",
"Ok",
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => People_List(),
),
);
},
);}
else {
FormHelper.showMessage(
context,
"Login",
"Login not Successfull",
"Ok", () {}
);
}
});
});
}
}
}
RegisterUser.dart
import 'model.dart';
class RegisterUser extends Model {
static String table = 'userDetails';
int id;
String firstName;
String lastName;
String mobileNum;
String emailId;
String address;
String userType;
String password;
RegisterUser({
this.id,
this.firstName,
this.lastName,
this.mobileNum,
this.emailId,
this.address,
this.userType,
this.password
});
static RegisterUser fromMap(Map<String, dynamic> map) {
return RegisterUser(
id: map["id"],
firstName: map['firstName'].toString(),
lastName: map['lastName'],
mobileNum: map['mobileNum'],
emailId: map['emailId'],
address: map['address'],
userType: map['userType'],
password: map['password']
);
}
Map<String, dynamic> toMap() {
Map<String, dynamic> map = {
'id': id,
'firstName': firstName,
'lastName': lastName,
'mobileNum': mobileNum,
'emailId': emailId,
'address': address,
'userType':userType,
'password':password
};
if (id != null) {
map['id'] = id;
}
return map;
}
}
db_service.dart
import 'package:customer/models/registerUser.dart';
import 'package:customer/utils/database_helper.dart';
Future<List<RegisterUser>> getUsers() async {
await DB.init();
List<Map<String, dynamic>> userDetails = await DB.query(RegisterUser.table);
return userDetails.map((item) => RegisterUser.fromMap(item)).toList();
}
Future<List<RegisterUser>> getLogin(String email, String password) async {
await DB.init();
List<Map<String, dynamic>> res = await DB.rawQuery("SELECT * FROM userDetails WHERE emailId = '$email' and password = '$password'");
if (res.length > 0) {
return res.map((item) => RegisterUser.fromMap(item)).toList();
//return new User.fromMap(res.first);
}
return null;
}
You need a line with dbService = something before you can do dbService.getUsers() because just saying DbService dbService; initializes it to be null.
It's like a paper with no phone number on it and you are trying to call someone with it. You need to write down a phone number on it.
I finally got the answer to my question.
I had to just instantiate the DBService.
i.e DBService dbService=new DBService();
class UserLoginState extends State<UserLogin>{
final reguser = RegisterUser();
String name,_password,_email;
var _formKey=GlobalKey<FormState>();
RegisterUser model;
DBService dbService=new DBService();
...
Related
I was following this tutorial on Youtube on how to create a database in Flutter app, I literally followed all the instructions on the tutorial but I keep getting this exception whenever I try to click the save button to save a new note to the database which indicates that NOT NULL constraint failed.
here
here is what my files look like:
note_model.dart:
class Note {
final int? id;
final String title;
final String content;
const Note({required this.title, required this.content, this.id});
factory Note.fromJson(Map<String, dynamic> json) => Note(
id: json['id'],
title: json['title'],
content: json['content'],
);
Map<String, dynamic> toJson() => {
'id': id,
'title': title,
'content': content,
};
#override
String toString() {
return "id: $id \n title: $title \n content: $content \n";
}
}
database_help:
import 'package:dummy_database/models/note_model.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static const int _version = 1;
static const String _dbName = "Notes.db";
static Future<Database> _getDB() async {
return openDatabase(join(await getDatabasesPath(), _dbName),
onCreate: (db, version) async => await db.execute(
"CREATE TABLE Note(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, content TEXT NOT NULL);"),
version: _version);
}
static Future<int> addNote(Note note) async {
final db = await _getDB();
return await db.insert("Note", note.toJson(),
conflictAlgorithm: ConflictAlgorithm.replace);
}
static Future<int> updateNote(Note note) async {
final db = await _getDB();
return await db.update("Note", note.toJson(),
where: 'id = ?',
whereArgs: [note.id],
conflictAlgorithm: ConflictAlgorithm.replace);
}
static Future<int> deleteNote(Note note) async {
final db = await _getDB();
return await db.delete(
"Note",
where: 'id = ?',
whereArgs: [note.id],
);
}
static Future<List<Note>?> getAllNotes() async {
final db = await _getDB();
final List<Map<String, dynamic>> maps = await db.query("Note");
if (maps.isEmpty) {
return null;
}
return List.generate(maps.length, (index) => Note.fromJson(maps[index]));
}
}
***here is the file that causing the exception: ***
import 'dart:developer';
import 'package:dummy_database/models/note_model.dart';
import 'package:dummy_database/services/database_helper.dart';
import 'package:flutter/material.dart';
class NoteScreen extends StatelessWidget {
final Note? note;
NoteScreen({Key? key, this.note}) : super(key: key);
final titleController = TextEditingController();
final contentController = TextEditingController();
#override
Widget build(BuildContext context) {
if (note != null) {
titleController.text = note!.title;
contentController.text = note!.content;
}
return Scaffold(
appBar: AppBar(
title: Text(note == null ? 'Add a note' : 'Edit note'),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 30),
child: Column(
children: [
const Padding(
padding: EdgeInsets.only(bottom: 40),
child: Center(
child: Text(
'What are you thinking about?',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 40.0),
child: TextFormField(
controller: titleController,
maxLines: 1,
decoration: const InputDecoration(
hintText: 'Title',
labelText: 'Note title',
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 0.75,
),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
))),
),
),
TextFormField(
controller: contentController,
decoration: const InputDecoration(
hintText: 'Type here the note',
labelText: 'Note content',
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 0.75,
),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
))),
keyboardType: TextInputType.multiline,
onChanged: (str) {},
maxLines: 5,
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: SizedBox(
height: 45,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
onPressed: () async {
final title = titleController.value.text;
final content = contentController.value.text;
log("title value is $title, \n content value is $content");
if (title.isEmpty || content.isEmpty) {
return;
}
final Note model =
Note(title: title, content: content, id: note?.id);
log(model.toString());
if (note == null) {
await DatabaseHelper.addNote(model);
} else {
await DatabaseHelper.updateNote(model);
}
Navigator.pop(context);
},
style: ButtonStyle(
shape: MaterialStateProperty.all(
const RoundedRectangleBorder(
side: BorderSide(
color: Colors.white,
width: 0.75,
),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
)))),
child: Text(
note == null ? 'Save' : 'Edit',
style: const TextStyle(fontSize: 20),
)),
),
)
],
),
),
);
}
}
I'm working on a login screen and I use TextFormField to insert a user's email and password. When I use a tablet emulator the keyboard immediately disappears after I click on it. It isn't for every emulator. With my real phone it works and also with another emulator. But with other three emulators it doesn't work. This are the imports:
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:prcarpolimi/Internet/NetworkCheck.dart';
import 'package:prcarpolimi/auth/signUp.dart';
import 'package:prcarpolimi/auth/forgot_password.dart';
import 'package:prcarpolimi/models/marker_to_pass.dart';
import 'package:prcarpolimi/models/userModel.dart';
import 'package:prcarpolimi/homepage.dart';
import 'package:prcarpolimi/services/services.dart';
import '../models/static_user.dart';
import 'package:intl/intl.dart';
And this is my code:
final Service loginService;
const Login({Key? key, required this.loginService}) : super(key: key);
#override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
UserModel userModel = UserModel();
static final _emailController = TextEditingController();
static final _passwordController = TextEditingController();
static final _formKey = GlobalKey<FormState>();
bool from = true;
Future<User?> loginUsingEmailPassword(
{required String email,
required String password,
required BuildContext context}) async {
User? user;
try {
user = await widget.loginService.signInWithemailandpass(email, password);
} on FirebaseAuthException catch (e) {
if (e.code == "user-not-found") {}
Fluttertoast.showToast(
msg: 'Login failed :( wrong email or password', fontSize: 20);
return null;
}
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(child: CircularProgressIndicator()),
);
return user;
}
_finishReservation(User user) async {
var data = await widget.loginService
.firebasefirestore()
.collection('users')
.doc(user.uid)
.collection('booking-out')
.get();
if (data.docs.isNotEmpty) {
for (var bookOut in data.docs) {
String data = bookOut.data()['date'];
final splitted = data.split('-');
String finalDate = splitted[1];
DateTime dayEnd = DateFormat("dd/MM/yyyy").parse(finalDate);
if (dayEnd.compareTo(DateTime.now()) < 0) {
await widget.loginService
.firebasefirestore()
.collection('users')
.doc(user.uid)
.collection('booking-out')
.doc(bookOut.data()['bookingId'])
.update({'status': 'f'});
}
}
}
var data2 = await widget.loginService
.firebasefirestore()
.collection('users')
.doc(user.uid)
.collection('cars')
.get();
if (data2.docs.isNotEmpty) {
for (var car in data.docs) {
await widget.loginService
.firebasefirestore()
.collection('users')
.doc(car.data()['uid'])
.collection('cars')
.doc(car.data()['cid'])
.collection('booking-in')
.get()
.then((ds) async {
if (ds.docs.isNotEmpty) {
for (var book in ds.docs) {
String data = book.data()['date'];
final splitted = data.split('-');
String finalDate = splitted[1];
DateTime dayEnd = DateFormat("dd/MM/yyyy").parse(finalDate);
if (dayEnd.compareTo(DateTime.now()) < 0) {
await widget.loginService
.firebasefirestore()
.collection('users')
.doc(user.uid)
.collection('cars')
.doc(book.data()['cid'])
.collection('booking-in')
.doc(book.data()['bookingId'])
.update({'status': 'f'});
}
}
}
});
}
}
}
#override
Widget build(BuildContext context) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
final screenText = MediaQuery.of(context).textScaleFactor;
final emailField = TextFormField(
key: const ValueKey(1),
autofocus: false,
style: TextStyle(fontSize: sizeHintText()),
controller: _emailController,
keyboardType: TextInputType.emailAddress,
onSaved: (value) {
_emailController.text = value!;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
prefixIcon: Icon(Icons.mail, size: sizeHintText()),
contentPadding: EdgeInsets.fromLTRB(screenWidth * 0.02,
screenHeight * 0.015, screenWidth * 0.02, screenHeight * 0.015),
hintText: "Email",
hintStyle: TextStyle(fontSize: sizeHintText()),
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(10))));
final passwordField = TextFormField(
key: const ValueKey(2),
autofocus: false,
style: TextStyle(fontSize: sizeHintText()),
controller: _passwordController,
obscureText: true,
onSaved: (value) {
_passwordController.text = value!;
},
textInputAction: TextInputAction.done,
decoration: InputDecoration(
prefixIcon: Icon(Icons.vpn_key, size: sizeHintText()),
contentPadding: EdgeInsets.fromLTRB(screenWidth * 0.02,
screenHeight * 0.015, screenWidth * 0.02, screenHeight * 0.015),
hintText: "Password",
hintStyle: TextStyle(fontSize: sizeHintText()),
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(10))));
Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: screenHeight * 0.1),
Text("Welcome to PrCar!",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: screenText * 45,
fontWeight: FontWeight.bold)),
SizedBox(height: screenHeight * 0.05),
SizedBox(
height: screenHeight * 0.2,
child: Image.asset("assets/prcarlogo.png",
fit: BoxFit.contain)),
SizedBox(height: screenHeight * 0.05),
emailField,
SizedBox(height: screenHeight * 0.02),
passwordField,
SizedBox(height: screenHeight * 0.05),
Row(children: [
SizedBox(width: screenWidth * 0.06),
GestureDetector(
child: Text('Forgot password?',
style: TextStyle(
decoration: TextDecoration.underline,
color: Colors.redAccent,
fontSize: screenText * 16)),
onTap: () =>
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const ForgotPasswordPage(),
))),
Text(' or ', style: TextStyle(fontSize: screenText * 12)),
GestureDetector(
key: Key("New Account"),
child: Text("Don't have an account?",
textAlign: TextAlign.start,
style: TextStyle(
decoration: TextDecoration.underline,
color: Colors.redAccent,
fontSize: screenText * 16)),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUp())))
]),
SizedBox(height: screenHeight * 0.06),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
key: const Key("clickButtom"),
height: screenHeight * 0.07,
width: screenWidth * 0.85,
child: MaterialButton(
color: Colors.redAccent,
onPressed: () async {
if (await NetworkCheck().check()) {
User? user = await loginUsingEmailPassword(
email: _emailController.text,
password: _passwordController.text,
context: context);
if (user != null) {
await widget.loginService
.firebasefirestore()
.collection('users')
.doc(user.uid)
.get()
.then((ds) {
userModel = UserModel.fromMap(ds);
StaticUser.email = userModel.email!;
StaticUser.uid = userModel.uid!;
StaticUser.firstName = userModel.firstName!;
StaticUser.secondName =
userModel.secondName!;
PassMarker.from = true;
_finishReservation(user);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(
homePageService: Service())));
});
}
} else {
Fluttertoast.showToast(
msg: 'No internet connection',
fontSize: 20);
}
},
child: Text("Login",
style: TextStyle(
color: Colors.white,
fontSize: screenText * 25))),
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
boxShadow: const [
BoxShadow(
color: Colors.deepPurple,
spreadRadius: 6,
blurRadius: 3)
]))
])
])));
}
}
you dont need to add this line
onSaved: (value) {
_passwordController.text = value!;
},
controller will automatically update text when you change in textformfield
ive been getting this error for days now but still cant figure it out. My objective is to put message response everytime user enter the same email into the snackbar but what i get is a null.
This is my signup screen.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:form_field_validator/form_field_validator.dart';
import 'package:formvalid/models/register_model.dart';
import 'package:http/http.dart' as http;
import 'package:formvalid/progressHUD.dart';
import 'package:formvalid/screens/login.dart';
class SignupScreen extends StatefulWidget {
const SignupScreen({Key? key}) : super(key: key);
#override
_SignupScreenState createState() => _SignupScreenState();
}
class RegisterAPI {
Future<RegisterResponse> register(
String name, String email, String password) async {
String url = 'http://api.staging.tarsoft.co/api/register';
final response = await http.post(Uri.parse('$url'),
body: {'name': name, 'email': email, 'password': password});
if (response.statusCode == 200 || response.statusCode == 401) {
print(response.body);
// print(response.statusCode);
return RegisterResponse.fromJson(json.decode(response.body));
} else {
print(response.body);
throw Exception('Failed to load data');
}
}
}
class _SignupScreenState extends State<SignupScreen> {
TextEditingController passController = new TextEditingController();
TextEditingController emailController = new TextEditingController();
TextEditingController nameController = new TextEditingController();
GlobalKey<FormState> formKey = GlobalKey<FormState>();
final scaffoldKey = GlobalKey<FormState>();
late RegisterResponse _user;
bool hidePassword = true;
bool isApiCallprocess = false;
#override
void initState() {
super.initState();
_user = new RegisterResponse();
}
#override
Widget build(BuildContext context) {
return ProgressHUD(
child: _uibuild(context),
inAsyncCall: isApiCallprocess,
opacity: 0.3,
);
}
Widget _uibuild(BuildContext context) {
final double height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
key: scaffoldKey,
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => LoginScreen()));
},
)),
backgroundColor: Color(0xFFffffff),
body: SingleChildScrollView(
child: Form(
key: formKey,
child: Container(
padding: EdgeInsets.only(left: 40, right: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: height * 0.04),
Text(
'Prizes and Suprises',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color(0xFF363f93)),
),
Text(
'Await you !',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color(0xFF363f93)),
),
SizedBox(
height: height * 0.03,
),
TextFormField(
controller: nameController,
onSaved: (input) => _user.name = input,
decoration: InputDecoration(labelText: 'Enter your name'),
validator: (value) {
if (value!.isEmpty ||
!RegExp(r'^[a-z A-Z]+$').hasMatch(value)) {
return 'Enter correct name';
} else {
return null;
}
}),
SizedBox(height: height * 0.05),
TextFormField(
controller: emailController,
onSaved: (input) => _user.email = input,
decoration: InputDecoration(labelText: 'Enter your email'),
validator: MultiValidator([
RequiredValidator(errorText: 'Enter your email'),
EmailValidator(errorText: 'Not A Valid Email')
])),
SizedBox(height: height * 0.05),
TextFormField(
controller: passController,
onSaved: (input) => _user.password = input,
decoration: InputDecoration(labelText: 'Enter your password'),
validator: MultiValidator([
RequiredValidator(errorText: 'Enter your password'),
MinLengthValidator(6,
errorText: 'Should be at least 6 characters')
]),
obscureText: hidePassword,
),
SizedBox(height: height * 0.05),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () {
final String name = nameController.text;
final String email = emailController.text;
final String password = passController.text;
if (validateAndSave()) {
setState(() {
isApiCallprocess = true;
});
RegisterAPI registerAPI = new RegisterAPI();
registerAPI
.register(name, email, password)
.then((value) => {
setState(() {
isApiCallprocess = false;
}),
if (value.token?.isNotEmpty ?? false)
{
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text(
'${_user.name}')))
}
else
{
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content:
Text('${_user.message}')))
}
});
print(_user.toJson());
}
},
child: Container(
margin: EdgeInsets.only(left: 100.0),
child: Padding(
padding: const EdgeInsets.only(left: 35, top: 10),
child: Text(
'Register',
style: TextStyle(color: Colors.white),
),
),
height: 40,
width: 120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Color(0xFF363f93),
),
)),
SizedBox(
height: height * 0.09,
),
],
),
],
),
),
),
),
);
}
bool validateAndSave() {
final form = formKey.currentState;
if (form!.validate()) {
form.save();
return true;
}
return false;
}
}
//ignore: must_be_immutable
class TextInput extends StatelessWidget {
final String textString;
TextEditingController textController;
final bool obscureText;
TextInput(
{Key? key,
required this.textString,
required this.textController,
required this.obscureText})
: super(key: key);
#override
Widget build(BuildContext context) {
return TextField(
style: TextStyle(color: Color(0xFF000000)),
cursorColor: Color(0xFF9b9b9b),
controller: textController,
keyboardType: TextInputType.text,
obscureText: obscureText,
decoration: InputDecoration(
hintText: this.textString,
hintStyle: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 15,
fontWeight: FontWeight.normal),
),
);
}
}
This is my responseregister
class RegisterResponse{
String? email;
String? password;
String? name;
String? token;
String? error;
String? message;
String? success;
RegisterResponse({this.email, this.password, this.name,this.token,this.error,this.message,this.success});
factory RegisterResponse.fromJson(Map<String, dynamic> json) =>
RegisterResponse(
name: json['name'],
email: json['email'],
password: json['password'],
token: json['token'] == null ? json['token'] : '',
error: json['error'],
message: json['email'],
success: json['Success']
);
Map<String, dynamic> toJson() {
Map<String, dynamic> map = {
'name': name,
'email': email,
'password': password,
};
return map;
}
}
this is in debugger console shows "the email has already been taken"
display null
When I clicking on login then every time showing an error occurs in dialog box
but in my debug console my shown login successfully
I do not understand why login is not happening, it is throwing catch error again and again
While my login in deb console is succesfully
And after login should go to homepage.
this is my auth.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:rest_api_login/utils/api.dart';
import 'package:http/http.dart' as http;
import 'package:rest_api_login/utils/http_exception.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Auth with ChangeNotifier {
var MainUrl = Api.authUrl;
var AuthKey = Api.authKey;
// String _token;
String _uid;
String _username;
DateTime _expiryDate;
Timer _authTimer;
bool get isAuth {
return token != null;
}
String get token {
if (_expiryDate != null &&
_expiryDate.isAfter(DateTime.now()) &&
_uid != null) {
return _uid;
}
}
String get uid {
return _uid;
}
String get username {
return _username;
}
Future<void> logout() async {
_username = null;
_uid = null;
_expiryDate = null;
if (_authTimer != null) {
_authTimer.cancel();
_authTimer = null;
}
notifyListeners();
final pref = await SharedPreferences.getInstance();
pref.clear();
}
void _autologout() {
if (_authTimer != null) {
_authTimer.cancel();
}
final timetoExpiry = _expiryDate.difference(DateTime.now()).inSeconds;
_authTimer = Timer(Duration(seconds: timetoExpiry), logout);
}
Future<bool> tryautoLogin() async {
final pref = await SharedPreferences.getInstance();
if (!pref.containsKey('userData')) {
return false;
}
final extractedUserData =
json.decode(pref.getString('userData')) as Map<String, Object>;
final expiryDate = DateTime.parse(extractedUserData['expiryDate']);
if (expiryDate.isBefore(DateTime.now())) {
return false;
}
_uid = extractedUserData['uid'];
_username = extractedUserData['username'];
_expiryDate = expiryDate;
notifyListeners();
_autologout();
return true;
}
Future<void> Authentication(
String username, String password, String endpoint) async {
try {
var url = Uri.parse('$MainUrl&action=$endpoint');
final responce = await http.post(url,
body: ({
'username': username,
'password': password,
}));
final responceData = json.decode(responce.body);
print(responceData);
if (responceData['error'] != null) {
throw HttpException(responceData['error']['msg']);
}
_uid = responceData['uid'];
_username = responceData['username'];
_expiryDate = DateTime.now()
.add(Duration(seconds: int.parse(responceData['expiresIn'])));
_autologout();
notifyListeners();
final prefs = await SharedPreferences.getInstance();
final userData = json.encode({
'uid': _uid,
'username': _username,
'expiryDate': _expiryDate.toIso8601String(),
});
prefs.setString('userData', userData);
print('check' + userData.toString());
} catch (e) {
throw e;
}
}
Future<void> login(String username, String password) {
return Authentication(username, password, 'login');
}
Future<void> signUp(String username, String password) {
return Authentication(username, password, 'registration');
}
}
This is my login.dart page
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rest_api_login/providers/auth.dart';
import 'package:rest_api_login/screens/home_Screen.dart';
import 'package:rest_api_login/screens/signup_screen.dart';
import 'package:rest_api_login/utils/http_exception.dart';
class LoginScreen extends StatefulWidget {
static const String routeName = "/login";
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final GlobalKey<FormState> _formKey = GlobalKey();
Map<String, String> _authData = {'username': '', 'password': ''};
Future _submit() async {
if (!_formKey.currentState.validate()) {
//invalid
return;
}
_formKey.currentState.save();
try {
await Provider.of<Auth>(context, listen: false)
.login(_authData['username'], _authData['password']);
} on HttpException catch (e) {
var errorMessage = 'Authentication Failed';
if (e.toString().contains('INVALID_EMAIL')) {
errorMessage = 'Invalid email';
_showerrorDialog(errorMessage);
} else if (e.toString().contains('EMAIL_NOT_FOUND')) {
errorMessage = 'This email not found';
_showerrorDialog(errorMessage);
} else if (e.toString().contains('INVALID_PASSWORD')) {
errorMessage = 'Invalid Password';
_showerrorDialog(errorMessage);
}
} catch (error) {
var errorMessage = 'Plaese try again later';
_showerrorDialog(errorMessage);
}
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
// backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
child: Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.65,
width: MediaQuery.of(context).size.width * 0.85,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(360),
bottomRight: Radius.circular(360)),
color: Colors.blue),
),
Container(
padding:
EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Sign In",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 40),
),
SizedBox(
height: 10,
),
Text(
"Sign in with your username or email",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 10),
),
Form(
key: _formKey,
child: Container(
padding: EdgeInsets.only(top: 50, left: 20, right: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Username or Email",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 12),
),
TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
prefixIcon: Icon(
Icons.person,
color: Colors.white,
)),
// validator: (value) {
// if (value.isEmpty || !value.contains('#')) {
// return 'Invalid email';
// }
// },
onSaved: (value) {
_authData['username'] = value;
},
),
SizedBox(
height: 10,
),
Text(
"Password",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 12),
),
TextFormField(
obscureText: true,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
prefixIcon: Icon(
Icons.vpn_key,
color: Colors.white,
)),
validator: (value) {
if (value.isEmpty || value.length < 5) {
return 'Password is to Short';
}
},
onSaved: (value) {
_authData['password'] = value;
},
),
Container(
padding: EdgeInsets.only(top: 40),
width: 140,
child: RaisedButton(
onPressed: () {
_submit();
},
shape: RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(10.0),
),
child: Text(
'Sign In',
style: TextStyle(color: Colors.white),
),
color: Colors.green),
),
Align(
alignment: Alignment.bottomRight,
child: InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (ctx) => SignUpScreen()));
},
child: Container(
padding: EdgeInsets.only(top: 90),
child: Text(
"Create Account",
style: TextStyle(
decoration: TextDecoration.underline,
color: Colors.blue,
fontSize: 16),
),
),
),
)
],
),
),
),
],
),
),
],
),
),
),
);
}
void _showerrorDialog(String message) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(
'An Error Occurs',
style: TextStyle(color: Colors.blue),
),
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
),
);
}
}
This is my main.dart page
import 'package:flutter/material.dart';
import 'package:login_and_signup/Providers/auth.dart';
import 'package:login_and_signup/Providers/signup_auth.dart';
import 'package:login_and_signup/Screens/home_screen.dart';
import 'package:login_and_signup/Screens/login.dart';
import 'package:login_and_signup/Screens/splash_screen.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: Auth(),
child: Consumer<Auth>(
builder: (context, auth, _) => MaterialApp(
title: 'Flutter demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity),
//home: LoginScreen(),
home: auth.isAuth!
? HomeScreen()
: FutureBuilder(
future: auth.tryautoLogin(),
builder: (context, snapshot) =>
snapshot.connectionState == ConnectionState.waiting
? SplashScreen()
: LoginScreen()),
),
),
);
}
}
This is my homepage.dart page
import 'package:flutter/material.dart';
import 'package:login_and_signup/Providers/auth.dart';
import 'package:login_and_signup/Screens/login.dart';
// import 'package:login_signup_with_api/Providers/auth.dart';
import 'package:provider/provider.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.of(context).pushReplacementNamed('/');
Provider.of<Auth>(context, listen: false).logout();
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: Text('logout'),
color: Colors.green,
)
// color: Colors.green,
// ),
),
);
}
}
I have a screen to add a customer's details. Name, company, mobile no.,email,profile picture. I have added validator to all the fields. Validator is working for all the fields but not for one field, the top one(Name). I dont know why. When I place the field below all the fields then the validator works but I want to keep the field on top. I want Name field to contain some value.
add_person.dart
import 'dart:io';
import 'package:email_validator/email_validator.dart';
import 'package:vers2cts/models/customer_model.dart';
import 'package:vers2cts/models/language.dart';
import 'package:vers2cts/models/languages_widget.dart';
import 'package:vers2cts/models/languages_model.dart';
import 'package:vers2cts/screens/people_list.dart';
import 'package:vers2cts/services/db_service.dart';
import 'package:vers2cts/utils/form_helper.dart';
import 'search_contacts.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:image_picker/image_picker.dart';
class AddPerson extends StatefulWidget {
String uname;
final String appBarTitle;
final CustomerModel customer;
AddPerson(this.uname,this.customer,this.appBarTitle);
#override
State<StatefulWidget> createState() {
return AddPersonState(uname,customer,appBarTitle);
}
}
class AddPersonState extends State<AddPerson> {
GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();
String uname,email,mobnum;
AddPersonState(this.uname,this.customer,this.appBarTitle);
bool engcheckbox=false;
String appBarTitle;
CustomerModel customer=new CustomerModel();
LanguagesModel langs=new LanguagesModel();
DBService dbService=new DBService();
bool showPassword = false;
DateTime _date=DateTime.now();
TextEditingController datefield=TextEditingController();
PickedFile _imageFile;
final ImagePicker _picker=ImagePicker();
TextEditingController custfNameController = TextEditingController();
TextEditingController custlNameController = TextEditingController();
TextEditingController custMobileNoController = TextEditingController();
TextEditingController custCompanyController = TextEditingController();
TextEditingController addrController = TextEditingController();
TextEditingController custEmailController = TextEditingController();
void getImage(ImageSource source) async{
final pickedFile=await _picker.getImage(
source:source);
setState(() {
_imageFile=pickedFile;
customer.cust_photo = _imageFile.path;
});
}
Future<Null> _selectDate(BuildContext context)async {
DateTime _datePicker = await showDatePicker(
context: context,
initialDate: _date,
firstDate: DateTime(1947),
lastDate: DateTime(2030),);
if (_datePicker != null && _datePicker != _date) {
setState(() {
_date = _datePicker;
String formattedDate = DateFormat('dd-MM-yyyy').format(_date);
datefield.text=formattedDate.toString();
print(datefield.text);
});
}
}
#override
Widget build(BuildContext context){
var selectedLanguages = languages.where((element) => element.selected);
TextStyle textStyle=Theme.of(context).textTheme.title;
var height = MediaQuery.of(context).size.height;
var width = MediaQuery.of(context).size.width;
var _minimumPadding = 5.0;
custfNameController.text = customer.first_name;
custlNameController.text = customer.last_name;
custMobileNoController.text = customer.mob_num;
custCompanyController.text=customer.org_name;
addrController.text=customer.addr;
custEmailController.text=customer.email_id;
return WillPopScope(
onWillPop: () {
moveToLastScreen();
},
child: Scaffold(
appBar: AppBar(
title: Text(appBarTitle),
elevation: 1,
actions: [
IconButton(
icon: Icon(
Icons.search,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => SearchContacts()));
},
),
],
),
body:Form(
key: globalFormKey,
child: Container(
padding: EdgeInsets.only(left: 16, top: 25, right: 16),
child:
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: ListView(
children: [
ImageProfile(customer.cust_photo),
SizedBox(
height: 35,
),
buildTextField("Name",custfNameController,
(value) => updatefName(value),(value)=>checkfname(value)),
buildTextField("Mobile",custMobileNoController,
(value) => updateMobile(value),(value)=>checkmobile(value)),
buildTextField("Company",custCompanyController,
(value) => updateCompany(value),(value)=>checkempty(value)),
buildTextField("Email",custEmailController,
(value) => updateEmail(value),(value)=>checkmail(value)),
Text("Address"),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: addrController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: const BorderSide(width: 2.0),)),
keyboardType: TextInputType.multiline,
minLines: 5,//Normal textInputField will be displayed
maxLines: 5, // when user presses enter it will adapt to it
onChanged: (value) {
this.customer.addr = value;
},
),
),
SizedBox(
height: height * 0.02,
),
Divider(),
SizedBox(
height: height * 0.02,
),
Row(
children: <Widget>[
Expanded(
child: Text("Show on Call",
style: textStyle,
)
),
SizedBox(
height: height * 0.02,
),
SizedBox(
height: 35,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
OutlineButton(
padding: EdgeInsets.symmetric(horizontal: 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
onPressed: () {},
child: Text("CANCEL",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.black)),
),
RaisedButton(
onPressed: () {
setState(() {
_saveCustomer();
});
},
//color: Colors.purpleAccent,
color: Theme.of(context).primaryColor,
padding: EdgeInsets.symmetric(horizontal: 50),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Text(
"SAVE",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
)
],
),
),
),
)));
}
Widget bottomSheet(){
return Container(
height: 100,
width: MediaQuery.of(context).size.width ,
margin: EdgeInsets.symmetric(
horizontal:20,
vertical:20,
),
child: Column(
children: <Widget>[
Text("Choose profile photo",
style: TextStyle(fontSize: 20.0),),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
onPressed: (){
getImage(ImageSource.camera);
},
icon:Icon(Icons.camera,color: Theme.of(context).primaryColor,), label:Text("camera")),
FlatButton.icon(
onPressed: (){
getImage(ImageSource.gallery);
},
icon:Icon(Icons.photo_library), label:Text("Gallery"))
],
)
],
),
);
}
//This is for 1st 3 Textfields name,mobile,company
Widget buildTextField(String labelText,tController,Function onChanged,Function validator) {
return Padding(
padding: const EdgeInsets.only(bottom: 35.0),
child: TextFormField(
controller:tController,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 3),
labelText: labelText,
labelStyle:TextStyle(),
floatingLabelBehavior: FloatingLabelBehavior.always,
),
onChanged: (String value) {
return onChanged(value);
},
validator:(String value) {
return validator(value);
},
),
);
}
void moveToLastScreen() {
Navigator.pop(context, true);
}
bool validateAndSave() {
final form = globalFormKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
void _saveCustomer() async {
if (validateAndSave()) {
var result;
var res;
var mob = await dbService.checkcustMobno(mobnum,uname);
var mail = await dbService.checkcustEmail(email,uname);
if (mob != null) {
FormHelper.showAlertDialog(
context, 'Error',
'Customer with this mobile number already exists');
}
else if (mail != null) {
FormHelper.showAlertDialog(
context, 'Error',
'Customer with this email id already exists');
}else {
if (customer.cust_id != null) { // Case 1: Update operation
result = await dbService.updateCustomer(customer);
} else { // Case 2: Insert Operation
result = await dbService.insertCustomer(customer);
}
if (result != 0) { // Success
moveToLastScreen();
FormHelper.showAlertDialog(
context, 'Status', 'Customer Saved Successfully');
} else { // Failure
FormHelper.showAlertDialog(
context, 'Status', 'Problem Saving Customer');
}
languages.forEach((lang) async {
print("${lang.name} : ${lang.selected}");
if (lang.selected) {
LanguagesModel language = LanguagesModel(lang: lang.name);
print("customer id from lang");
print(customer.cust_id);
await dbService.insertLanguages(language);
}
});
}
}
}
String updatefName(String value) {
customer.first_name = custfNameController.text;
customer.cre_by=uname;
print(uname);
}
String updatelName(String value) {
if(value.isEmpty)
customer.last_name = " ";
else
customer.last_name = custlNameController.text;
}
String updateMobile(value) {
customer.mob_num = custMobileNoController.text;
mobnum=value;
}
String updateEmail(value) {
customer.email_id = custEmailController.text;
email=value;
}
String updateCompany(String value) {
customer.org_name = custCompanyController.text;
}
String checkfname(String value){
if(value.isEmpty)
{
return "First name can't be null";
}
return null;
}
String checkempty(String value){
print("checkempty called");
if(value.isEmpty)
{
return "Can't be null";
}
return null;
}
String checkmobile(String value) {
print("checkmobile called");
if(value.isEmpty)
{
return 'Please enter phone no.';
}
if(value.length<6)
{
return 'Please enter a valid phone no.';
}
return null;
}
String checkmail(String value){
print("checkmail called");
if(value.isEmpty)
{
return 'Please Enter E-mail address';
}
if (!EmailValidator.validate(value)) {
return 'Please enter a valid Email';
}
return null;
}
}
Replace the ListView (that the buildTextFields are its children) with a Column and wrap the Column with a SingleChildScrollView.