After new Login app show old user data from firebase - flutter

I am trying to display current user data from Firebase, and it works totally fine, but when I logout and login with a new email ID, the app also shows previous user data instead of new user login data.
My signIn function in Signin page
class LoginPage extends StatefulWidget {
//when user is login then save their userid and after use this for fetching current user data
//this help in StudentData.dart page
var userId;
#override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
//for Validation
final _key = GlobalKey<FormState>();
//for geeting input and store email & password
var email = "";
var password = "";
//for Loading Indicator
bool isLodaing = false;
//for login
Future userLogin() async {
//check internet is on or not
final ip = context.read<InternetProvider>();
await ip.checkInternetConnection();
//for checking Internet
if (ip.hasInternet == false) {
openSnackbar(context, "Check your internet connection", Colors.red);
} else {
try {
UserCredential userCredential = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
//when user loged in that time save user id that help after for fetch data in StudentData.dart page
// widget.userId = userCredential.user!.uid;
setState(() {
widget.userId = userCredential.user!.uid;
print("User id is : " + userCredential.user!.uid);
});
print("Widget User id is : " + widget.userId);
//show succuful log-in meesage
openSnackbar(
context, "Log-in Successfull", Color.fromARGB(255, 70, 213, 92));
//after login go to profile Page
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => FirstPage()));
} on FirebaseAuthException catch (e) {
//for no user Found
if (e.code == 'user-not-found') {
//for stoping the loading indicator when user get this error
Future.delayed(
Duration(seconds: 0),
() {
setState(() {
isLodaing = false;
});
},
);
//show Snack Bar when this error occur
openSnackbar(context, "No User Found for this e-mail", Colors.red);
}
//for Wrong Password
else if (e.code == 'wrong-password') {
//for stoping the loading indicator when user get this error
Future.delayed(
Duration(seconds: 0),
() {
setState(() {
isLodaing = false;
});
},
);
//show Snack Bar when this error occur
openSnackbar(context, "Wrong Password", Colors.red);
}
}
}
}
#override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: HexColor("#F9B684"),
body: GestureDetector(
//when user tap on screen tahat time keybord disumissed
//this is use for avoiding overflow screen
onTap: () => FocusScope.of(context).unfocus(),
child: SingleChildScrollView(
child: Column(
// this is main Column
children: [
//Heading
Container(
margin: EdgeInsets.only(top: 80, left: 20),
padding: EdgeInsets.only(left: 75, top: 13),
height: 80,
width: 265,
// color: Colors.white,
child: Text(
'Login',
style: TextStyle(
fontFamily: 'Ubuntu',
fontWeight: FontWeight.bold,
fontSize: 43,
color: HexColor("#2D0C03"),
),
),
),
//for image
Container(
margin: EdgeInsets.only(left: 10),
height: 200,
width: 265,
// color: Colors.white,
child: Image.asset("assets/images/login.gif",
fit: BoxFit.cover),
),
const SizedBox(height: 17),
//for TextFileds
Form(
key: _key,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 23.0),
child: Column(
children: [
//for E-mail Text Filed
TextFormField(
keyboardType: TextInputType.emailAddress,
//for move to cursor next Text automatically
textInputAction: TextInputAction.next,
//for autofil e-mail
autofillHints: [AutofillHints.email],
controller: emailController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(
Icons.email,
color: HexColor("#002C00"),
),
hintText: "e-mail",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(33)),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: HexColor("#002C00")),
borderRadius: BorderRadius.circular(25.7),
),
enabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(25.7),
),
),
//for validation
validator: (value) =>
value != null && !EmailValidator.validate(value)
? 'Enter valid e-mail'
: null,
),
const SizedBox(height: 10),
//for Password Text Filed
TextFormField(
controller: passwordController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
prefixIcon: Icon(
Icons.password,
color: HexColor("#002C00"),
),
hintText: "password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(33)),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: HexColor("#002C00")),
borderRadius: BorderRadius.circular(25.7),
),
enabledBorder: UnderlineInputBorder(
borderSide:
const BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(25.7),
),
),
//for validation
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter password";
}
return null;
},
),
//for forget Password
Container(
margin: const EdgeInsets.only(top: 4),
// color: Colors.yellow,
height: 35,
width: MediaQuery.of(context).size.width,
alignment: Alignment.bottomRight,
child: TextButton(
onPressed: () {
//goto Forget Password Screen
nextScreen(context, ForgetPassword_Page());
},
child: const Text(
"Forgot Password",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Gotham',
color: Color(0xff1778F2),
fontSize: 14.5),
),
),
),
const SizedBox(height: 9),
//for sign-in Button
SizedBox(
height: 50,
width: 170,
child: ElevatedButton.icon(
style: ElevatedButton.styleFrom(
primary: HexColor("#98504B"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
),
//for loading indicator and Text
icon: isLodaing
? const SizedBox()
: const Icon(Icons.arrow_forward, size: 24),
label: isLodaing
? Row(
children: [
//for circular indicator
Container(
margin:
const EdgeInsets.only(left: 7),
height: 25,
width: 25,
child: CircularProgressIndicator(
color: HexColor("#2D0C03"),
strokeWidth: 3.5,
backgroundColor: Colors.white,
),
),
//for text
Container(
margin:
const EdgeInsets.only(left: 7),
child: Text(
"Please Wait..",
style: TextStyle(
fontFamily: 'Gotham',
color: Colors.white),
),
),
],
)
: const Text(
'Sign-in',
style: const TextStyle(
fontFamily: 'Gotham', fontSize: 22),
),
//here we call method name signup for storing data in firebase
onPressed: () async {
//for validation
if (_key.currentState!.validate()) {
isLodaing = true;
setState(() {
//when user enter email & password then store those email and passwors in variable which intialize in top
email = emailController.text;
password = passwordController.text;
});
//for Showing Loaing Indicator
Future.delayed(
Duration(seconds: 3),
() {
setState(() {
isLodaing = true;
});
},
);
//for user login
userLogin();
}
//after run above line of code this Stop the Loading Indicator
Future.delayed(
Duration(seconds: 3),
() {
setState(() {
isLodaing = false;
});
},
);
},
),
),
//for sign-up opotion below login button
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Does Not Have Account? '),
TextButton(
onPressed: () {
nextScreen(context, RegistrationPage());
},
child: const Text(
"Sign-UP",
style: TextStyle(
letterSpacing: 0.2,
fontFamily: "Ubuntu",
fontSize: 16,
color: Color(0xff1778F2),
),
),
)
],
),
),
],
),
),
),
]),
),
),
),
);
}
}
UserData controller Class:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:get/get.dart';
import 'package:gtu_all_in_one/Pages/LoginPage.dart';
//this class help for fetching current user info from firebase
class StudentDataController extends GetxController {
final firebaseInstance = FirebaseFirestore.instance;
//after data fetch insert data in this
Map StudentProfileData = {
'name': '',
'EnrollmentNo': '',
'Email': '',
'Branch&Sem': ''
};
//create loginpage instance for getting current user userid , using this we fetch the data
LoginPage authController = LoginPage();
#override
void onReady() {
super.onReady();
getStudentProfileData();
}
Future<void> getStudentProfileData() async {
// print("user id ${authController.userId}");
try {
var response = await firebaseInstance
.collection('users')
.where('user_Id', isEqualTo: authController.userId)
.get();
// response.docs.forEach((result) {
// print(result.data());
// });
if (response.docs.length > 0) {
StudentProfileData['name'] = response.docs[0]['name'];
StudentProfileData['EnrollmentNo'] = response.docs[0]['EnrollmentNo'];
StudentProfileData['Email'] = response.docs[0]['Email'];
StudentProfileData['Branch&Sem'] = response.docs[0]['Branch&Sem'];
}
print(StudentProfileData);
} on FirebaseException catch (e) {
print(e);
} catch (error) {
print(error);
}
}
}
And profile Page where i trying to display current user data:
class ProfilePage extends StatefulWidget {
const ProfilePage({Key? key}) : super(key: key);
#override
State<ProfilePage> createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
//when user come in profile page after login that time this create instance of StudentDataController and go to StudentData Page
final StudentDataController controller = Get.put(StudentDataController());
#override
Widget build(BuildContext context) {
// for logout button
final sp = context.watch<SignInProvider>();
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Center(
child: Column(
children: [
SizedBox(height: 300),
Text("Name : ${controller.StudentProfileData['name']} "),
Text(
"Enrollment No : ${controller.StudentProfileData['EnrollmentNo']} "),
Text("Email : ${controller.StudentProfileData['Email']} "),
Text(
" Branch& Sem : ${controller.StudentProfileData['Branch&Sem']} "),
SizedBox(height: 10),
SizedBox(height: 10),
//for Opening QR Code Scanner
SizedBox(
height: 50,
width: 250,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: HexColor("#48EDC5"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(22),
),
),
child: Row(
children: [
//for text
Container(
margin: const EdgeInsets.only(left: 13),
child: Text(
"Mark Attendance",
style: TextStyle(
fontFamily: 'Gotham',
color: HexColor("#002C00"),
fontSize: 20),
),
),
//for Icone
Container(
margin: EdgeInsets.only(left: 5),
child: Icon(
Icons.qr_code_scanner,
size: 22,
color: HexColor("#002C00"),
),
),
],
),
//goto QR Code Scanner Page
onPressed: () {
nextScreen(context, QRCodeScanner());
},
),
),
SizedBox(height: 10),
//for LogOut Button
SizedBox(
height: 50,
width: 150,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: HexColor("#48EDC5"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(22),
),
),
child: Row(
children: [
//for text
Container(
margin: const EdgeInsets.only(left: 13),
child: Text(
"log Out",
style: TextStyle(
fontFamily: 'Gotham',
color: HexColor("#002C00"),
fontSize: 20),
),
),
//for Icone
Container(
margin: EdgeInsets.only(left: 5),
child: Icon(
Icons.arrow_forward_ios,
size: 22,
color: HexColor("#002C00"),
),
),
],
),
//goto SignUp Page
onPressed: () {
sp.userSignOut();
nextScreenReplace(context, FirstPage());
},
),
),
],
),
),
),
);
}
}

Related

Flutter Image Picker to Image URL

i have the following code below. ive used image_picker package to upload pictures to be used as profile pictures. ive commented my previous code that uses an image url instead. my question is if there's a way to convert the images uploaded to images url, that way, i can display the profile picture when i get into the home screen.
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'dart:io';
import 'package:cloud_functions/cloud_functions.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:ibchat/pages/verify_email_page.dart';
import 'package:ibchat/screens/screens.dart';
import 'package:ibchat/theme.dart';
import 'package:image_picker/image_picker.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import '../app.dart';
class SignUpScreen extends StatefulWidget {
static Route get route => MaterialPageRoute(
builder: (context) => const SignUpScreen(),
);
const SignUpScreen({Key? key}) : super(key: key);
#override
State<SignUpScreen> createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
final auth = firebase.FirebaseAuth.instance;
final functions = FirebaseFunctions.instance;
final _formKey = GlobalKey<FormState>();
PickedFile? _imageFile;
final ImagePicker _picker = ImagePicker();
//final _profilePictureController = TextEditingController();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _designationController = TextEditingController();
final _companyController = TextEditingController();
final _emailRegex = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+");
bool _loading = false;
Future<void> _signUp() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Set Firebase display name and profile picture
List<Future<void>> futures = [
/*if (_profilePictureController.text.isNotEmpty)
creds.user!.updatePhotoURL(_profilePictureController.text),*/
/*if (_picker.toString().isNotEmpty)
creds.user!.updatePhotoURL(_picker.toString()),*/
creds.user!.updateDisplayName(_nameController.text),
];
await Future.wait(futures);
// Create Stream user and get token using Firebase Functions
final callable = functions.httpsCallable('createStreamUserAndGetToken');
final results = await callable();
// Connect user to Stream and set user data
final client = StreamChatCore.of(context).client;
await client.connectUser(
User(
//image: _profilePictureController.text,
//image: _picker.toString(),
id: creds.user!.uid,
name: _nameController.text,
extraData: {
"email": _emailController.text,
"designation": _designationController.text,
"company": _companyController.text,
}),
results.data,
);
// Navigate to verify email page
await Navigator.of(context).pushReplacement(VerifyEmailPage.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(e.message ?? 'Verification error')),
);
} catch (e, st) {
logger.e('Sign up error', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.red, content: Text('An error occured')),
);
}
setState(() {
_loading = false;
});
}
}
String? _nameInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Name cannot be empty';
}
return null;
}
String? _emailInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Email cannot be empty';
}
if (!_emailRegex.hasMatch(value)) {
return 'Not a valid email';
}
return null;
}
String? _passwordInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Password Cannot be empty';
}
if (value.length <= 6) {
return 'Password needs to be longer than 6 characters';
}
return null;
}
#override
void dispose() {
//_profilePictureController.dispose();
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
_designationController.dispose();
_companyController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Image.asset('assets/images/logo.png', scale: 2),
backgroundColor: Colors.transparent,
),
body: (_loading)
? const Center(
child: SizedBox(
height: 100,
width: 100,
child: CircularProgressIndicator(color: AppColors.accent)))
: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
onWillPop: () async => false,
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 24),
child: Text(
'Registeration',
style: GoogleFonts.lato(
fontSize: 28, fontWeight: FontWeight.w800),
),
),
/*Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _profilePictureController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Picture URL',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.url,
),
),*/
imageProfile(),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _nameController,
validator: _nameInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Name',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
autofillHints: const [
AutofillHints.name,
AutofillHints.username
],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _emailController,
validator: _emailInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Email',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.emailAddress,
autofillHints: const [AutofillHints.email],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _passwordController,
validator: _passwordInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Password',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
obscureText: true,
enableSuggestions: false,
autocorrect: false,
keyboardType: TextInputType.visiblePassword,
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _designationController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Designation',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _companyController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Company',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
),
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.all(12.0),
child: SizedBox(
height: 50,
width: 250,
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
))),
onPressed: _signUp,
child: Text('Sign Up',
style: GoogleFonts.lato(
fontSize: 21,
fontWeight: FontWeight.bold,
color: Colors.black)),
),
),
),
const SizedBox(
height: 20,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Divider(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Already a Member?',
style: Theme.of(context).textTheme.subtitle2),
const SizedBox(width: 8),
TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
primary: AppColors.accent),
onPressed: () {
Navigator.of(context).push(SignInScreen.route);
},
child: const Text('Sign In',
style: TextStyle(color: AppColors.secondary)),
),
],
),
],
),
),
),
),
);
}
Widget imageProfile() {
return Center(
child: Stack(
children: <Widget>[
CircleAvatar(
radius: 34,
backgroundImage: _imageFile == null
? const AssetImage("assets/images/profile_default.png")
as ImageProvider
: FileImage(File(_imageFile!.path)),
),
Positioned(
bottom: -2,
right: -1,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: ((builder) => bottomSheet()),
);
},
child: const Icon(CupertinoIcons.camera_fill,
color: AppColors.accent, size: 20)),
)
],
),
);
}
Widget bottomSheet() {
return Container(
height: 100,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: Column(
children: <Widget>[
const Text(
"Upload a Profile Photo",
style: TextStyle(
fontSize: 18.0,
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
icon: const Icon(CupertinoIcons.camera_fill),
onPressed: () {
takePhoto(ImageSource.camera);
},
label: const Text("Camera")),
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
icon:
const Icon(CupertinoIcons.photo_fill_on_rectangle_fill),
onPressed: () {
takePhoto(ImageSource.gallery);
},
label: const Text("Photos")),
],
)
],
));
}
void takePhoto(ImageSource source) async {
final pickedFile = await _picker.getImage(source: source);
setState(() {
_imageFile = pickedFile!;
});
}
}

How to make a simple admin page in flutter with a given email and password in flutter?

How can I add an admin page to the existing pages?
I just want one default admin to enter which will only display users from Firebase. I would like a specific email and password to be given which will allow access for that one admin.
I'm attaching the login page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'startuppage.dart';
class MyLogin extends StatefulWidget {
const MyLogin({Key? key}) : super(key: key);
#override
State<MyLogin> createState() => _MyLoginState();
}
class _MyLoginState extends State<MyLogin> {
//editing controller
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
int _success = 1 ;
late String _userEmail = "";
final user = FirebaseAuth.instance.currentUser;
Future SignIn() async {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim()
);
}
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
//color: Color(0xFFaac8ba),
gradient: LinearGradient
(begin: Alignment.bottomLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFFde6262),
Color(0xFFffb88c)
]
),
),
child : Scaffold(
backgroundColor: Colors.transparent, //By default, in scaffold the bg color is white.
body: Container(
padding: const EdgeInsets.only(top: 130, left: 35, right: 0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Welcome Back\nTo Check-it.",
style: TextStyle(
color: Colors.black,
fontSize: 30,
fontFamily: 'Montserrat',
letterSpacing: 3,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 50.0,
),
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
hintText: "Email",
prefixIcon: Icon(Icons.mail, color: Colors.black,)
),
),
const SizedBox(
height: 20.0,
),
TextField(
controller:passwordController,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
hintText: "Password",
prefixIcon: Icon(Icons.lock, color: Colors.black,)
),
),
const SizedBox(
height: 50.0,
),
ElevatedButton(
onPressed: () async{
// _signIn();
SignIn();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const Imageslider()),
);
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.black12),
),
child: const Text("Login",
style: TextStyle(
fontSize: 18,
color: Colors.black54),
),
),
const SizedBox(
height: 10.0,
),
Container(
alignment: Alignment.bottomCenter,
child: Text(
_success == 1
?''
: (
_success == 2
? 'Sign-in successful! '
: 'Sign-in failed!'),
style: const TextStyle(
color: Colors.white70,
)
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
Navigator.pushNamed(context,'signup');
},
child: const Text ('New User? Sign Up',
style : TextStyle(
decoration: TextDecoration.underline,
fontSize: 18,
color: Colors.black45,
),
)),
],
),
],
),
),
),
),
);
}
}
Sign Up Page Code :
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'login.dart';
import 'startuppage.dart';
final FirebaseAuth _auth = FirebaseAuth.instance;
class Mysignup extends StatefulWidget {
const Mysignup({Key? key}) : super(key: key);
#override
State<Mysignup> createState() => _MysignupState();
}
class _MysignupState extends State<Mysignup> {
Future<FirebaseApp> _initializeFirebase() async {
FirebaseApp firebaseApp = await Firebase.initializeApp();
return firebaseApp;
}
//editing controller
final TextEditingController name = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
late bool _success;
bool isLoading = false;
Future<User?> _register(String name, String email, String password) async{
FirebaseAuth _auth = FirebaseAuth.instance;
FirebaseFirestore _firestore = FirebaseFirestore.instance;
try {
UserCredential userCrendetial = await _auth.createUserWithEmailAndPassword(email: emailController.text, password: passwordController.text);
print("Account created Succesfull");
userCrendetial.user?.updateDisplayName(name);
await _firestore.collection('users').doc(_auth.currentUser?.uid).set({
"name": name,
"email": email,
"uid": _auth.currentUser?.uid,
});
return userCrendetial.user;
} catch (e) {
print(e);
return null;
}
}
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
gradient: LinearGradient
(colors: [
Color(0xFF02aab0),
Color(0xFF00cdac)
],
),
),
child : Scaffold(
backgroundColor: Colors.transparent, //By default, in scaffold the bg color is white.
body: Container(
padding: const EdgeInsets.only(top: 150, left: 35, right: 35),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Let's Create Together.",
style: TextStyle(
color: Colors.black,
fontSize: 30,
letterSpacing: 3,
fontWeight: FontWeight.bold,
),
),
const SizedBox(
height: 40.0,
),
TextField(
controller:name,
keyboardType: TextInputType.name,
decoration: const InputDecoration(
hintText: "Name",
prefixIcon: Icon(Icons.account_circle_rounded, color: Colors.black,)
),
),
const SizedBox(
height: 20.0,
),
TextField(
controller:emailController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
hintText: "Email",
prefixIcon: Icon(Icons.mail, color: Colors.black,)
),
),
const SizedBox(
height: 20.0,
),
TextField(
controller:passwordController,
obscureText: true,
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
hintText: "Password",
prefixIcon: Icon(Icons.lock, color: Colors.black,)
),
),
const SizedBox(
height: 80.0,
),
ElevatedButton(
onPressed: () async{
if (name.text.isNotEmpty &&
emailController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
setState(() {
isLoading = true;
});
_register(name.text, emailController.text, passwordController.text).then((user) {
if (user == null) {
setState(() {
isLoading = false;
});
Navigator.push(
context, MaterialPageRoute(builder: (_) => MyLogin()));
print("Account Created Sucessful");
} else {
print("Login Failed");
setState(() {
isLoading = false;
});
}
});
} else {
print("Please enter all the fields");
}
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.black12),
),
child: const Text("Sign Up",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black54),
),
),
],
),
),
),
),
);
}
}
I'm a beginner in FLutter. Please help. Thanks in advance!
You'll want to use StreamBuilder to respond to the FirebaseAuth.instance.authStateChanges() stream that is shown in the first snippet on getting the current user, then detect whether it is the admin user who signed in based on their UID, and then show them the admin page of your UI.
Something like:
child: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, userSnapshot) {
if (userSnapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (userSnapshot.connectionState == ConnectionState.done) {
if (!userSnapshot.hasData) {
// TODO: return screen where they sign in
}
else if (userSnapshot.data!.uid == "uidOfYourAdminUser") {
// TODO: return admin screen
}else{
// TODO: return screen for regular signed in user
}
}
}
)

Flutter Failed assertion: 'initialValue == null || controller == null': is not true

I am trying to fetch data entered in firestore to my TextFormField in order to make it as a profile updating section but while doing so I am facing this error Failed assertion: line 150 pos 15: 'initialValue == null || controller == null': is not true. I am unfamiliar with it can anyone please guide me where I am making mistake how can I resolve it? Also is its the correct approach I am making profile updating section. User will first enter the data, it will be empty by default and when the user will again come back to this screen the user should be shown the previous saved data that's exactly what I want.
Here's my code:
final TextEditingController _peopletohangoutwithController =
TextEditingController();// Controller
// rest of the code
FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance
.collection("userpreferences")
.doc(FirebaseAuth.instance.currentUser!.uid)
.get(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
print(snapshot.hasData);
print(snapshot.data!["peopletohangoutwith"]);
}
return Column(
children: [
const SizedBox(
height: 50,
),
Row(
children: [
Align(
alignment: Alignment.topLeft,
child: DelayedDisplay(
delay: const Duration(seconds: 1),
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onPressed: () {
Navigator.of(context).pop();
},
),
)),
),
const Align(
alignment: Alignment.topCenter,
child: DelayedDisplay(
delay: Duration(seconds: 1),
child: Text(
"Hang out with",
style: TextStyle(
fontSize: 26,
color: Colors.white,
fontFamily: "ProductSans",
fontWeight: FontWeight.bold),
),
),
),
],
),
const SizedBox(
height: 50,
),
const DelayedDisplay(
delay: Duration(seconds: 2),
child: Center(
child: Padding(
padding: EdgeInsets.only(left: 10, right: 10),
child: Text(
"What type of people you want to hang out with",
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontFamily: "ProductSans",
fontWeight: FontWeight.bold),
),
),
),
),
const SizedBox(
height: 50,
),
DelayedDisplay(
delay: const Duration(seconds: 2),
child: Padding(
padding: const EdgeInsets.only(left: 30, right: 30),
child: TextFormField(
initialValue: snapshot.data!["peopletohangoutwith"],
controller: _peopletohangoutwithController,
maxLines: 10,
decoration: InputDecoration(
hintText: "Write in as detail as possible",
fillColor: Colors.white,
filled: true,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.white,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(0),
borderSide: const BorderSide(
color: Colors.white,
width: 2.0,
),
),
)),
),
),
const SizedBox(
height: 100,
),
DelayedDisplay(
delay: const Duration(seconds: 2),
child: Center(
child: FloatingActionButton.extended(
label: const Text('Save'),
backgroundColor: const Color(0xFF2A3B6A),
icon: const Icon(
Icons.save_as_outlined,
size: 24.0,
),
onPressed: () async {
if (_peopletohangoutwithController.text.isEmpty) {
Get.snackbar(
"Error",
"Please explain your preference",
colorText: Colors.white,
);
} else {
FirebaseFirestore.instance
.collection("userpreferences")
.doc(FirebaseAuth.instance.currentUser!.uid)
.set({
"peopletohangoutwith":
_peopletohangoutwithController.text,
});
}
},
),
),
),
],
);
},
),
How bout you fetch the user data before going to the edit page.. Pass the data to the page in a constructor and enter the data in the text editing controller in init state.
EDIT: Sorry. Didn't knoqw you were a beginner.
Let's assume you're getting your data from some database eg Firebase. Ensure you have a usermodel. Models make data so much easier to manage.
Soo,,
class UserModel{
String _userName;
String _tikTok;
String get userName => _userName;
String get tiktok => _tikTok;
UserModel.fromSnapshot(DocumentSnapshot snapshot){
_userName = snapshot.data()["userName"];
_tikTok = snapshot.data()["tikTok"];
}
}
This userModel can be used to propagate the profile page. Eg, if you got the data from firestore using streamBuilder, the builder would be sth like
(context, snapshot){
if(!snapshot.hasData}{
return LoadingWidget();
}else{
UserModel userModel = UserModel.fromSnapshot(snapshot.data);
return Scaffold(body: blah blah Text(userModel.userName) `and so forth`
I lost track of my brackets there, but you get the point.
Send the userModel to the next page via constructors, and initiate the data in initstate. Coz init state is the first function executed the moment the page loads. Even before it starts building widgets.
This is the code for the edit page.
class EditProfilePage extends StatefulWidget {
final UserModel userModel;
EditProfilePage({
Key key,
#required this.userModel,
}) : super(key: key);
#override
State<EditProfilePage> createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
TextEditingController nameController;
TextEditingController tiktokAccountController;
#override
void initState() {
super.initState();
if (widget.userModel != null) {
nameController = TextEditingController(
text: widget.userModel.userName,
);
tiktokAccountController = TextEditingController(
text: widget.userModel.tiktok,
);
}
}
#override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: nameController,
decoration: InputDecoration(
hintText: "Username",
),
),
SizedBox(
height: 10,
),
TextField(
controller: tiktokAccountController,
decoration: InputDecoration(
hintText: "Tik Tok Username",
),
),
],
);
}
}
So, when you're going to the edit page from the profile page, you would call Navigator.of(context).push(EditBlahBlah(userModel: userModel,),)
Where userModel is the userModel you're viewing on the profile page. I hope that helps.
Only one of the TextFormField's initialValue or controller can be used.
Use TextEditingController with initial value:
final controller = TextEditingController('the initial value');

Can i Select Multiple Accounts in a Banking app and pay them different amounts at the same time in flutter?

import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import 'package:money_formatter/money_formatter.dart';
import 'package:shukela_app/api/banking_app_api.dart';
import 'package:shukela_app/screens/stokvel_detail.dart';
import 'package:shukela_app/screens/stokvels.dart';
import 'package:shukela_app/utils/constants.dart';
import 'package:shukela_app/utils/global_variables.dart';
import 'package:sizer/sizer.dart';
import 'package:shukela_app/model/bankingapp_model.dart';
import '../utils/user_preferences.dart';
class PayMultipleStokvelScreen extends StatefulWidget {
const PayMultipleStokvelScreen({Key? key}) : super(key: key);
#override
State<PayMultipleStokvelScreen> createState() =>
_PayMultipleStokvelScreenState();
}
TextEditingController txtSearch = TextEditingController();
TextEditingController txtAmount = TextEditingController();
class _PayMultipleStokvelScreenState extends State<PayMultipleStokvelScreen> {
String? selectedType;
bool hasText = false;
String buttonText = "PAY NOW";
bool isLoading = false;
Widget? showHideIcon() {
if (hasText) {
return IconButton(
icon: const Icon(
Icons.clear,
color: AppColors.primaryBlue,
),
onPressed: () {
txtSearch.clear();
setState(() {
hasText = false;
});
},
);
} else {
return null;
}
}
// void _showMultiSelectDialog(BuildContext context) async {
// await showDialog(
// context: context,
// builder: (ctx) {
// return MultiSelectDialog(
// items: _animals.map((e) => MultiSelectItem(e, e)).toList(),
// initialValue: _selectedAnimals,
// onConfirm: (values) {...},
// );
// },
// );
// }
double? balance;
final _formKey = GlobalKey<FormState>();
var selectedValue;
List<StokvelDetail> selectedStokvel = [];
#override
void initState() {
super.initState();
balance = double.parse(UserPreferences.getBalance() ?? '');
}
mf() {
MoneyFormatter mf = MoneyFormatter(amount: balance!);
return mf;
}
StokvelListState currentState = StokvelListState.showAllListState;
#override
Widget build(BuildContext context) => KeyboardDismisser(
gestures: const [GestureType.onTap],
child: SafeArea(
child: Scaffold(
backgroundColor: AppColors.secondaryColor,
appBar: AppBar(
backgroundColor: AppColors.secondaryColor,
elevation: 0,
title: const Text('Pay Multiple Stokvel',
style: screenTitleTextStyle),
leading: IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: AppColors.primaryBlue,
),
onPressed: () => Navigator.pop(context),
),
),
body: Form(
key: _formKey,
child: Column(
children: [
SizedBox(height: 5.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TypeAheadFormField<Stokvel?>(
debounceDuration: const Duration(milliseconds: 500),
hideSuggestionsOnKeyboardHide: false,
suggestionsBoxDecoration: const SuggestionsBoxDecoration(
constraints: BoxConstraints(maxHeight: 450),
color: AppColors.secondaryColor,
borderRadius: BorderRadius.all(Radius.circular(10))),
textFieldConfiguration: TextFieldConfiguration(
style: const TextStyle(
color: AppColors.primaryBlue,
fontSize: 15.0,
fontWeight: FontWeight.bold,
),
controller: txtSearch,
onChanged: (value) {
setState(() {
hasText = true;
});
},
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.search,
color: AppColors.primaryBlue,
),
suffixIcon: showHideIcon(),
hintText: 'Search Stokvel',
border: const OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4.0),
borderSide:
const BorderSide(color: AppColors.primaryBlue),
),
),
),
validator: (val) {
if (val!.isEmpty) {
return "Please select stokvel";
}
return null;
},
suggestionsCallback: BankingAppApi.getStokvelSuggestions,
itemBuilder: (context, Stokvel? suggestion) {
final stokvel = suggestion!;
//
return ListTile(
trailing: SizedBox(
height: 20.0,
width: 20.0,
child: Container(
color: AppColors.primaryBlue,
),
),
title: Text(
stokvel.stokvelName!,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue,
),
),
subtitle: Text(
stokvel.stokvelType!,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue),
),
);
},
noItemsFoundBuilder: (context) => const SizedBox(
height: 60,
child: Center(
child: Text(
'No Stokvel Found.',
style: TextStyle(fontSize: 20),
),
),
),
onSuggestionSelected: (Stokvel? suggestion) {
final stokvel = suggestion!;
setState(() {
txtSearch.text = stokvel.stokvelName!;
hasText = true;
});
stokvelID = stokvel.stokvelID;
memberID = stokvel.memberID;
},
),
),
SizedBox(
height: 4.h,
),
SizedBox(height: 3.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TextFormField(
controller: txtAmount,
decoration: const InputDecoration(
labelStyle: TextStyle(
color: AppColors.primaryBlue,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
suffixText: "ZAR",
border: OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
labelText: 'Amount',
contentPadding:
EdgeInsets.only(left: 20, right: 15, bottom: 8),
),
keyboardType: TextInputType.number,
style: const TextStyle(
fontSize: 20.0,
fontFamily: Fonts.primaryFont,
color: AppColors.primaryBlue),
validator: (val) {
if (val!.isEmpty) {
return "Please enter amount";
}
return null;
},
),
),
SizedBox(height: 3.h),
Container(
height: 6.h,
width: 98.w,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: TextField(
readOnly: true,
style: const TextStyle(
fontSize: 18.0, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: "Wallet Balance : R " + mf().output.nonSymbol,
border: const OutlineInputBorder(
borderSide:
BorderSide(color: AppColors.primaryBlue),
borderRadius: BorderRadius.horizontal()),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1, color: AppColors.primaryBlue),
),
),
),
),
SizedBox(height: 3.h),
Container(
height: 50,
width: 400,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white)),
child: isLoading
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CircularProgressIndicator(
color: AppColors.secondaryColor),
SizedBox(width: 24),
Text(
"Submitting payment...",
style: TextStyle(
color: AppColors.secondaryColor),
)
],
)
: Text(
buttonText,
style: const TextStyle(
fontFamily: Fonts.primaryFont,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue),
),
onPressed: () {
if (_formKey.currentState!.validate()) {
if (double.parse(txtAmount.text) <= balance!) {
setState(
() {
isLoading = true;
},
);
stokvelTransact.amount =
double.parse(txtAmount.text);
stokvelTransact.memberID = memberID;
stokvelTransact.stokvelID = stokvelID;
stokvelTransact.transactionTypeID = 1;
api
.stokvelDeposit(stokvelTransact,
"StokvelTransaction/StokvelTransact")
.then(
(value) => setState(
() {
Future.delayed(
const Duration(seconds: 3));
isLoading = false;
if (value == "Success") {
ScaffoldMessenger.of(context)
.showSnackBar(snackBar(
content:
'Payment made succesfully',
duration: 5));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(snackBar(
content:
'We have encountered technical problems, Try again later',
duration: 5));
}
},
),
)
.catchError(
(err) {
setState(() {
isLoading = false;
});
ScaffoldMessenger.of(context).showSnackBar(
snackBar(
content: err.toString(), duration: 7));
},
);
} else {
ScaffoldMessenger.of(context).showSnackBar(snackBar(
content: "Insuficient funds!", duration: 7));
}
}
},
),
),
],
),
),
),
),
);
}
The above code is for the single page that I want to achieve this
This is what I want to achieve or any suggestions are accepted, I want to mark the Group of Stokvels I want to pay and pay them different accounts I don't know if it's possible please I'm new in flutter it a project I have to get it done as soon as possible this is the source code for my whole payment page, for now, I'm able to pay a single Stokvel Group but I want to select multiple
I highly suggest starting with formatting of the current code - its hard to read and with that hard to maintain.
The simple idea would be:
use List<StokvelDetail> selectedStokvel = []; you created to add the Stokvel's in every time you select Stokvel in SearchBar
Add Map<int,double> amounts = {}; <StokvelId, amount> to keep track of the amount you want to send to each Stokvel
Based on selectedStokvel build multiple 'amount window' widgets
Before submit verify walletBalance >= amounts.values.reduce((a,b)=> a + b)
For each selectedStokvel call api.stokvelDeposit(stokvelTransact, ...
I would primarly focus on spliting this code to multiple Widget classes, there are many schools but I like to have around 150 lines of code in single file at most.
From what i see your file can be easily split into:
Column(
children: [
SizedBox(),
SearchBar(),
SizedBox(),
AmountInput(), --> StokvelAmountInput() for each selectedStokvel
SizedBox(),
WalletBalance(),
SizedBox(),
SubmitButton(),
]),
```

!_debugLocked is not true when making changes

I'm getting this error when i make any changes to my app, i need to re run my app to get rid of this error. I tried to make some changes to my navigation but nothing changes. I also i'm searching for hours on the google to find something useful but i can't find anything to make it work.
Note: I'm beginner on Flutter development
Main.dart:
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:tasker/screens/HomeScreen.dart';
import 'package:progress_dialog/progress_dialog.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
#override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
late ProgressDialog progressDialog;
FirebaseAuth auth = FirebaseAuth.instance;
String email = "";
String password = "";
#override
Widget build(BuildContext context) {
progressDialog = ProgressDialog(context);
Future<String> getCurrentUserEmail() async {
FirebaseUser user = await auth.currentUser();
String userEmail = user.email.toString();
return userEmail;
}
// Navigate user to HomeScreen if already singed in
if (auth.currentUser() != null) {
Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(context, new MaterialPageRoute(builder: (context) => HomeScreen(userEmail: '',)));
}
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login"),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
/*
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(50.0)),*/
child: Image(
image: NetworkImage('https://cdn-icons-png.flaticon.com/512/1055/1055672.png'),
)),
),
),
Padding(
padding: const EdgeInsets.only(left:15.0, right: 15.0, top:30, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.email = value;
});
},
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter email'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.password = value;
});
},
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
TextButton(
onPressed: (){
// open reset password screen
},
child: Text(
'Forgot Password?',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(20)),
child: TextButton (
onPressed: () async {
progressDialog.show();
try {
AuthResult authResult = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email.toString(),
password: password.toString()
);
FirebaseUser user = authResult.user;
if (user == null) {
progressDialog.hide();
print("logged in");
await Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(context, new MaterialPageRoute(builder: (context) => HomeScreen(userEmail: '',)));
}
} catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
SizedBox(
height: 130,
),
TextButton(
onPressed: (){
// open reset password screen
},
child: Text(
'New user? Sign up!',
style: TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold),
),
),
],
),
),
floatingActionButton: FloatingActionButton(onPressed: () {
},),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat
);
}
}
I found multiple issues with the code, but the one which caused the debugLocked error was using future directly inside the build method, you either put the future in a FutureBuilder or run outside the build method.
Here is the code fixed:
import 'dart:io';
import 'package:tasker/screens/HomeScreen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_progress_dialog/flutter_progress_dialog.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
#override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
late ProgressDialog progressDialog;
FirebaseAuth auth = FirebaseAuth.instance;
String email = "";
String password = "";
Future<String>? getCurrentUserEmail() async {
User user = await auth.currentUser!;
String userEmail = user.email.toString();
return userEmail;
}
// Navigate user to HomeScreen if already singed in
#override
void initState() {
progressDialog = ProgressDialog(
child: Container(
child: Text('Loading'),
),
);
// TODO: implement initState
super.initState();
}
Future<void>? checkUserLoggedIn() async {
if (auth.currentUser != null) {
await Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(
context,
new MaterialPageRoute(
builder: (context) => HomeScreen(
userEmail: '',
)));
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login"),
),
body: ProgressDialog(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
child: Image(
image: NetworkImage(
'https://cdn-icons-png.flaticon.com/512/1055/1055672.png'),
)),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 30, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.email = value;
});
},
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter email'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.password = value;
});
},
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
TextButton(
onPressed: () {
// open reset password screen
},
child: Text(
'Forgot Password?',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () async {
showProgressDialog();
try {
UserCredential authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: email.toString(),
password: password.toString());
User user = authResult.user!;
if (user == null) {
dismissProgressDialog();
print("logged in");
await Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(
context,
new MaterialPageRoute(
builder: (context) => HomeScreen(
userEmail: '',
)));
}
} catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
SizedBox(
height: 130,
),
TextButton(
onPressed: () {
// open reset password screen
},
child: Text(
'New user? Sign up!',
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat);
}
}