Bad state: field does not exist within the DocumentSnapshotPlatform problem - flutter

I want to do the sign-in method and I face this run time error ,I don't know the reason cause it or how to solve it.
I want to checks all cases for login
my code is:
ElevatedButton(
onPressed: logIn,
child: StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
// try{
print('inside bulder method');
if (snapshot.connectionState ==
ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator());
}
if (snapshot.hasData) {
print('have account');
return home();
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Invalid email/password'),
backgroundColor: Colors.red.shade400,
margin: const EdgeInsets.fromLTRB(6, 0, 3, 0),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.white,
onPressed: () {},
)));
return Text('there is something error');
}
},
),)
and login method:
``Future<void> logIn() async {
print('inside login method');
if (_formKey.currentState!.validate()) {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
print('end try');
} catch (e) {
if (emailController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Invalid email/password'),
backgroundColor: Colors.red.shade400,
margin: const EdgeInsets.fromLTRB(6, 0, 3, 0),
behavior: SnackBarBehavior.floating,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.white,
onPressed: () {},
)));
print("after check");
}
}
}
}
`
`
each textFormField is have the correct controller
and because of this problem I can't run this method correctly

Related

Flutter Web - after password reset success, unable to login unless refresh

I'm using Flutter and Firebase Auth to have a password recovery screen in Flutter Web that takes the users email 'oobCode' to verify the email via URL parameters.
Then set their new password and allow them to login with their new password.
This works very well with one problem - once the new password is set, I send them to a new route to login but they cannot login unless they refresh the page manually or start a new browser.
There is no error of any kind BUT if they "refresh" the page then they can login without problems with the new password.
I'm using an ElevatedButton.icon to trigger the changing of the password and then using Navigator.pushAndRemoveUntil to send them to the login screen with no way to 'back' to the reset screen.
Here's the button:
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.teal.shade900,
minimumSize: const Size.fromHeight(50),
),
icon: processingReset
? const Center(
child: SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(color: kQptColorLightGrey200),
),
)
: const Icon(Icons.lock_open, size: 32),
label: const Text('Reset Password'),
onPressed: () async {
String? submitStatus = "";
ScaffoldMessengerState scaffoldState = ScaffoldMessenger.of(context);
if (_formKey.currentState!.validate()) {
/// show a progress indicator on the button icon
try {
setState(() {
processingReset = true;
_hasException = false;
});
await resetPassword();
/// with success, then redirect to the login page
submitStatus = 'Password reset successfully';
if (!mounted) return;
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return const LoginScreen();
},
),
(route) => false,
);
} on FirebaseAuthException catch (e) {
submitStatus = "Error: ${e.message}";
setState(() {
processingReset = false;
_hasException = true;
});
}
scaffoldState.showSnackBar(
SnackBar(
backgroundColor: _hasException ? kQptColorRed : kQptColorGreen,
duration: const Duration(seconds: 3),
content: Text(submitStatus),
),
);
}
},
),
then, the login screen has a Column with several controls that take the users email and new password:
children: <Widget>[
LoginTextFormField(
inputTextInputAction: TextInputAction.next,
inputTextEditingController: _emailTextFormFieldController,
inputLabelText: "Enter your Email here",
inputObscureText: false,
inputValidatorText: "Please enter your Email",
),
const SizedBox(height: 20),
LoginTextFormField(
inputTextInputAction: TextInputAction.done,
inputTextEditingController: _passwordTextFormFieldController,
inputLabelText: "Enter your Password here",
inputObscureText: true,
inputValidatorText: "Please enter your Password",
),
const SizedBox(height: 20),
ElevatedButton.icon(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.teal.shade900,
minimumSize: const Size.fromHeight(50),
),
icon: const Icon(Icons.lock_open, size: 32),
label: const Text('Sign In'),
onPressed: signIn,
),
const SizedBox(
height: 24,
),
GestureDetector(
child: const Text(
"Forgot Password?",
style: TextStyle(
decoration: TextDecoration.underline,
),
),
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const ForgotPasswordScreen(),
),
),
),
],
),
This calls a signin function that processes the login (works very well and produces no errors)
Future signIn() async {
String feedbackText = 'Processing your login...';
if (_formKey.currentState!.validate()) {
print('login screen form is valid');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
//duration: const Duration(seconds: 2),
content: Text(feedbackText),
),
);
try {
print('login screen starting login process');
print('login screen: ${_passwordTextFormFieldController.text}');
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailTextFormFieldController.text.trim(),
password: _passwordTextFormFieldController.text.trim(),
//password: 'bad pass',
);
// disable automatic login by disabling persistence on web platforms
await FirebaseAuth.instance.setPersistence(Persistence.LOCAL);
print('login screen setting persistence');
} on FirebaseAuthException catch (e) {
print('login screen: we have an error');
if (e.code == 'user-not-found' || e.code == 'invalid-email') {
print('No user found for that email or badly formatted email');
feedbackText = 'No user found for that email or badly formatted email';
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
feedbackText = 'Wrong password provided for that user.';
} else {
print('general error: ${e.message}');
feedbackText = 'General error: ${e.message}';
}
/// display an error message
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(feedbackText),
),
);
}
}
/// end of validate
}
and then the main.dart is called to route the user to main navigation:
class _MyAppState extends State<MyApp> {
User tempUser = User();
/// TODO: change this to false before deploy
bool resetFlag = false;
String inputCode = '';
String inputMode = 'resetPassword';
#override
void initState() {
/// look to see if we have a queryString parameter and then set the flag for reset or not
print('In Main initState');
if (Uri.base.queryParameters['oobCode'] != null) {
/// we have a parameter
print('In Main initState, oobCode found');
if (Uri.base.queryParameters['oobCode']!.isNotEmpty) {
/// it's not empty - assign the value
inputCode = Uri.base.queryParameters['oobCode']!;
print('In Main initState, oobCode is not null');
/// set the reset flag
resetFlag = true;
print('In Main initState, resetFlag is set to $resetFlag');
}
}
super.initState();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
showPerformanceOverlay: false,
debugShowCheckedModeBanner: false,
title: 'Scheduler',
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
primarySwatch: Colors.teal,
textTheme: const TextTheme(
/// for Small headlines
headlineSmall: TextStyle(
fontSize: 11,
color: Colors.black,
),
/// for Form elements
bodyMedium: TextStyle(
fontSize: 17,
color: kQptColorTeal,
),
titleLarge: TextStyle(fontSize: 22, color: kQptColorTeal, fontWeight: FontWeight.bold),
titleSmall: TextStyle(fontSize: 13, color: Colors.black87, fontWeight: FontWeight.bold),
),
),
/// if we have a URI Parameter it will be for a password reset, branch based on that
home: resetFlag
? UserManagementScreen(
inputCode: inputCode,
inputMode: inputMode,
)
: StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) {
/// we have a user, grab the Id and create a
/// User from the Uid value
/// then pass this into the CalendarScreen and ProfileScreen
print('in main screen: StreamBuilder snapshot has data');
return FutureBuilder<SchedulerUser>(
future: SchedulerUtils.getSchedulerUser(FirebaseAuth.instance.currentUser!.uid),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
print('in main screen: FutureBuilder entry');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
tempUser = snapshot.data;
print('in main screen future builder tempuser: $tempUser');
return MainNavScreen(inputSchedulerUser: tempUser);
} else if (snapshot.hasError) {
print("we have an error while getting the snapshot:${snapshot.error}");
return const ErrorScreen();
} else {
print('in main screen future builder no data: $tempUser');
// no data?...test, should never be hit.
return const ErrorScreen();
}
} else {
return const Center(child: CircularProgressIndicator());
}
},
);
} else {
return const LoginScreen();
}
},
),
routes: {
/// Primary Calendar Screen
CalendarScreen.id: (context) => CalendarScreen(inputSchedulerUser: tempUser),
/// When navigating to the "/login" route, build the LoginScreen.
LoginScreen.id: (context) => const LoginScreen(),
/// Profile Screen
//ProfileScreen.id: (context) => ProfileScreen(inputSchedulerUser: tempUser),
/// Main Navigation screen
MainNavScreen.id: (context) => MainNavScreen(inputSchedulerUser: tempUser),
/// Reset Password
UserManagementScreen.id: (context) => UserManagementScreen(inputMode: inputMode, inputCode: inputCode),
},
);
}
}
So, my question is, is there something I'm missing or a way "refresh" the web page app programmatically after the user has changed their password?

flutter close alert dialog builder after speech recognition finished

Hello friends i am working on speech recognition in flutter i made custom alert dialogue like native dialog when user click on button alert dialog appear and when user speak it show text on alert dialog my problem is that i want when user finishing his speech alert dialogue will automatically close please let me know how i can perform this task?
stt.SpeechToText speechToText = stt.SpeechToText();
bool islistening = false;
late String text = 'Example:Genesis chapter 1 verse 5';
bool complete=false;
final GlobalKey _dialogKey = GlobalKey();
ValueNotifier<bool> buttonClickedTimes =ValueNotifier(false);
_showDialog() async {
showDialog(
context:context,
barrierDismissible: true,
builder: (BuildContext context) {
return StatefulBuilder(
key: _dialogKey,
builder: (context, setState) {
return Container(
child: Dialog(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const AvatarGlow(
glowColor: Colors.blue,
endRadius: 80,
duration: Duration( milliseconds: 2500),
repeat: true,
showTwoGlows: true,
repeatPauseDuration: Duration( milliseconds: 150),
child: Material(
elevation: 5,
shape: CircleBorder(),
child: CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.mic, color: Colors.blue, size: 40,),
radius: 40,
),
),
),
Text(text),
const SizedBox(height: 10),
TextButton(
onPressed: () => Navigator.pop(context, false), // passing false
child: const Text('Cancel Voice'),
),
],
),
),
),
);
},
);
},
);
}
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
void _listen() async {
if (!islistening) {
bool available = await speechToText.initialize(
onStatus: (val) => print('onStatus: $val'),
onError: (val) => print('onError: $val'),
);
if (available) {
setState(() {
islistening = true;
});
speechToText.listen(
onResult: (result) =>
setState(() {
text = result.recognizedWords;
if (_dialogKey.currentState != null && _dialogKey.currentState!.mounted && speechToText.isListening) {
_dialogKey.currentState!.setState(() {
text =result.recognizedWords;
});}
else{
if(text.contains('Genesis')){
setState(() {
String bigSentence =text;
var voice= bigSentence.split(" ");
var bookname=voice[0];
var booknumber=1;
int chapternumber=int.parse(voice[2]);
int versenumber=int.parse(voice[4]);
if(_regExp.hasMatch(chapternumber.toString())&&_regExp.hasMatch(versenumber.toString())){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Allverse(bookname, booknumber,chapternumber, versenumber)),
);
}else{
Fluttertoast.showToast(
msg: "check chapter number or versenumber",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
});
}
}
})
);
}
} else
{
setState(() => islistening = false);
speechToText.stop();
}
}

make function await flutter

I have this variable
dynamic _permission = true;
after clicked on button. I need to display sncakbar if _permission= false thats mean user has no permission to access the page else go to page.
but I faced an issue that _permission always equal true.
even if permission return false from api.
here is the code
Future<void> checkPermesssion() async {
String api_token = await getToken();
final response = await http.post(
Uri.parse(PermissionURL),
headers: {'Accept': 'application/json',
'Authorization': 'Bearer $api_token'
},
);
var permission = jsonDecode(response.body)['permission'];
setState(() {
_permission = permission;
});
}
and here is the button code
child: ElevatedButton(
onPressed: () {
checkPermesssion();
_permission ?
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => page()))
:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'You don\'t have permession to access this page '),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(50),
elevation: 30,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.yellow,
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
},
How can I do that please
Try this for button's code :
child: ElevatedButton(
onPressed: () async{
await checkPermesssion();
_permission ?
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => page()))
:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'You don\'t have permession to access this page '),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(50),
elevation: 30,
action: SnackBarAction(
label: 'Dismiss',
disabledTextColor: Colors.white,
textColor: Colors.yellow,
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
},

having problem with flutter dialog box, after catching an error its showing me a black page

I have created a Dialog Widgets, It will show the Dialog+progeress indicator when a user login and signup. As usual dialogue box. Its works perfectly when there is no error like authencated user and password if you provide it will show the Dialog perfectly.
but when I put the wrong email id or password or make any mistake its show me a black blank page where I need to restart the app again. I want that if I am in signup mode if the error occurred it will show me the error message and keep me on the login page, the same thing for the registration page. I user Navigator.pop(context) to stop the dialogue but its stops the dialogue and show me a black blank page. But when it finds an error like I put a wrong email it takes me to the black page, I want that if it's found any error after showing the message it will keep me on my login page, so I can put a valid email and password.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:ride_share_app/AllScreen/mainscreen.dart';
import 'package:ride_share_app/AllScreen/registrationScreen.dart';
import 'package:ride_share_app/AllWidgets/progressDailog.dart';
import 'package:ride_share_app/main.dart';
class LogInScreen extends StatelessWidget {
static const String idScreen = 'loginScreen';
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
void loginAutentcatUser(BuildContext context) async {
try {
showDialog(context: context,
builder: (BuildContext contex){
return ProgressDialog(message: 'Authenticating Please wait',);
});
final firebaseUser = (await _firebaseAuth
.signInWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.catchError((errMsg) {
Navigator.pop(context);
displayToastMessage('Error Msg 01: ' + errMsg.toString(), context);
}))
.user;
if (firebaseUser != null) {
userRef.child(firebaseUser.uid).once().then(
(DataSnapshot snap) {
if (snap.value != null) {
Navigator.pushNamedAndRemoveUntil(
context, MainScreen.idScreen, (route) => false);
displayToastMessage('You are Loggied in', context);
}
else {
Navigator.pop(context);
_firebaseAuth.signOut();
displayToastMessage(
'User does not found, Create new account', context);
}
},
);
} else{
Navigator.pop(context);
displayToastMessage('Error occured', context);
}
} on PlatformException catch (err) {
Navigator.pop(context);
displayToastMessage('Error: 02 '+ err.toString(), context);
}catch (err) {
Navigator.pop(context);
displayToastMessage('Error: 03 ' + err.toString(), context);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image(
height: 350,
width: 250,
image: AssetImage('images/logo.png'),
),
Text(
'Login As Rider',
style: TextStyle(fontFamily: 'Brand Bold', fontSize: 24),
),
SizedBox(
height: 08,
),
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(
Icons.email,
color: Colors.black,
),
labelText: 'Email',
labelStyle:
TextStyle(color: Colors.black, fontSize: 15.0)),
),
SizedBox(
height: 08,
),
TextField(
controller: passwordController,
obscureText: true,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(
Icons.password,
color: Colors.black,
),
labelText: 'Password',
labelStyle:
TextStyle(color: Colors.black, fontSize: 15.0)),
),
SizedBox(
height: 08,
),
ElevatedButton(
onPressed: () {
if (emailController.text.isEmpty ||
!emailController.text.contains(RegExp(
'^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]+.[com]'))) {
displayToastMessage('Email is not valid', context);
}
else if (passwordController.text.isEmpty ||
passwordController.text.length < 8) {
displayToastMessage(
'password must be 9 cherectars', context);
}
else{
loginAutentcatUser(context);
}
},
child: Text('Login')),
TextButton(
onPressed: () {
Navigator.pushNamedAndRemoveUntil(context,
RegistrationScrren.idScreen, (route) => false);
},
child: Text('Create New Account..'))
],
),
),
),
),
);
}
}
this is my whole code for user login.
void loginAutentcatUser(BuildContext context) async {
try {
showDialog(context: context,
builder: (BuildContext contex){
return ProgressDialog(message: 'Authenticating Please wait',);
});
final firebaseUser = (await _firebaseAuth
.signInWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.catchError((errMsg) {
Navigator.pop(context);
displayToastMessage('Error Msg 01: ' + errMsg.toString(), context);
}))
.user;
if (firebaseUser != null) {
userRef.child(firebaseUser.uid).once().then(
(DataSnapshot snap) {
if (snap.value != null) {
Navigator.pushNamedAndRemoveUntil(
context, MainScreen.idScreen, (route) => false);
displayToastMessage('You are Loggied in', context);
}
else {
Navigator.pop(context);
_firebaseAuth.signOut();
displayToastMessage(
'User does not found, Create new account', context);
}
},
);
} else{
Navigator.pop(context);
displayToastMessage('Error occured', context);
}
} on PlatformException catch (err) {
Navigator.pop(context);
displayToastMessage('Error: 02 '+ err.toString(), context);
}catch (err) {
Navigator.pop(context);
displayToastMessage('Error: 03 ' + err.toString(), context);
}
}
this code shows that if any error occurs or catch it will use Navigator.pop(context) to stop the dialogue.
The issue lies here :
void loginAutentcatUser(BuildContext context) async {
try {
showDialog(context: context,
builder: (BuildContext contex){
.....
.....
}catch (err) {
Navigator.pop(context);
displayToastMessage('Error: 03 ' + err.toString(), context);
}
Note that the context that you are passing to the navigator when calling pop is the context of the LogInScreen widget, which is apparently the only route in the navigator and why you are left with a black screen. You shold be calling
Navigator.pop(contex);
With contex, minus the t that is how you named the dialog context, or even better be more explicit about it and rename contex to something more sensible like dialogContext :
void loginAutentcatUser(BuildContext context) async {
try {
showDialog(context: context,
builder: (BuildContext dialogContext){
.....
.....
}catch (err) {
Navigator.pop(dialogContext);
displayToastMessage('Error: 03 ' + err.toString(), context);
}
now its clear in your code that you are popping the dialog and no the entire route.

Circular progress indicator not showing in flutter

I am trying to show an CircularProgressIndicator whenever user presses on register button, here is my code:
onPressed: () async{
if (_email.isNotEmpty && _password.isNotEmpty) {
startProgressIndicator();
FirebaseAuth mAuth = FirebaseAuth.instance;
UserCredential credential = await mAuth.createUserWithEmailAndPassword(email: _email, password: _password);
print(credential.user!.email);
//stopProgressIndicator();
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(
"Please enter all information!",
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight: FontWeight.bold
),
),
backgroundColor: Colors.black,
elevation: 5,
duration: Duration(
seconds: 3
),
action: SnackBarAction(
label: "close",
onPressed: (){
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
));
}
startProgressIndicator():
CircularProgressIndicator startProgressIndicator() {
return CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.orange),
backgroundColor: Colors.black,
strokeWidth: 5,
);
}
stopProgressIndicator():
CircularProgressIndicator stopProgressIndicator() {
return CircularProgressIndicator(
value: 0,
);
}
The loading icon doesn't appear at all.
All colors are correct(i.e. background color and progress bar color are different)
What is the issue here?
EDIT: I added the following code but it still isn't working:
Column(
children: [
<Other widgets>
Visibility(
visible: _isProgressVisible,
child: CircularProgressIndicator(),
)
]
)
and I set _isProgressVisible to true and false:
if (_email.isNotEmpty && _password.isNotEmpty) {
setState(() {
_isProgressVisible = true;
});
FirebaseAuth mAuth = FirebaseAuth.instance;
UserCredential credential = await mAuth.createUserWithEmailAndPassword(email: _email, password: _password);
print(credential.user!.email);
setState(() {
_isProgressVisible = false;
});
}
You are not showing the returned widget anywhere, startProgressIndicator() returns the widget but you're just calling not rendering it,
Either use like this
showCupertinoDialog(
useRootNavigator: true,
barrierDismissible: false,
context: context,
builder: (context) {
return startProgressIndicator();
},
);
If you want to show that somewhere else you can do that like this
Container(
margin: const EdgeInsets.all(16),
child: Column(children: [
Visibility(
visible: showIndicator,
child: startProgressIndicator()),
const SizedBox(height: 10),
RaisedButton(
child: const Text('Here'),
onPressed: () => setState(() => showIndicator = !showIndicator),
)
]),
);
return startProgressIndicator();
That's just simple mistake
You have to return widget;