I want to verify if the phone number the user enter is in firebase, so I am using a showDialog to show a spinner, I want to dismiss the showdialog if that phone number already exist. I have tried setState to but the showddialog won't dismiss automatically avail
_phoneExist(phone) {
if (loading) {
showDialog(
context: context,
builder: (c) {
return Center(
child: SpinKitChasingDots(
color: Colors.brown,
size: 50.0,
),
);
});
}
firestoreInstance
.collection("partners")
.where("phone", isEqualTo: phone)
.getDocuments()
.then((value) {
value.documents.forEach((result) {
if (result.exists) {
print(result['phone']);
setState(() {
_userExist = true;
loading = false;
});
} else {
print('ghhgghgh');
}
});
});
if (_userExist) {
Scaffold.of(context).showSnackBar(snackBar2('$phone Aleady Exists'));
setState(() {
_userExist = false;
});
} else {
print('gghhgghgchgc');
print(phone);
// _registerUser();
}
}
You can try with the below lines
BuildContext buildContext;
_phoneExist(phone) {
if (loading) {
showDialog(
context: context,
builder: (BuildContext context) {
buildContext = context; // Assign your context to buildcontext
return Center(
child: SpinKitChasingDots(color: Colors.brown,size: 50.0,
),
);
});
}
firestoreInstance
.collection("partners").where("phone", isEqualTo: phone).getDocuments()
.then((value) {
value.documents.forEach((result) {
if (result.exists) {
setState(() {
_userExist = true;
loading = false;
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.pop(buildContext);
}); // By adding this you can close your pop up
});
} else {
}
});
});
if (_userExist) {
Scaffold.of(context).showSnackBar(snackBar2('$phone Aleady Exists'));
setState(() {
_userExist = false;
});
} else {
// _registerUser();
}
}
To hide a dialog you can use:
Navigator.pop(context);
If your app has multiple Navigator objects you can use:
Navigator.of(context, rootNavigator: true).pop();
You can see the docs here: https://api.flutter.dev/flutter/material/showDialog.html
Related
I'm trying to login in users using a third party api. But the problem is whenever an error occurs and the catch error is executed the "then" function that holds the navigation to the HomeScreen also is executed. Please is there a way to login user only when there is no error.
void signIn() {
setState(() {
_isLoading = true;
});
final isValid = _formKey.currentState!.validate();
if (isValid == false) {
setState(() {
_isLoading = false;
});
return;
} else {
setState(() {
_isLoading = true;
});
Provider.of<Authorization>(context, listen: false)
.loginUser(
_emailController.text.trim(),
_passwordController.text.trim(),
)
.catchError((error) {
const snackBar = SnackBar(
backgroundColor: Colors.red,
content: Text("An error occured please try again."),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}).then((_) {
setState(() {
_isLoading = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => const HomeScreen()),
),
);
});
}
}
Thanks in advance.
You can use another way to run this function and make it easier to you to understand and also more easy to code
void signIn() async{
setState(() {
_isLoading = true;
});
final isValid = _formKey.currentState!.validate();
if (isValid == false) {
setState(() {
_isLoading = false;
});
return;
} else {
setState(() {
_isLoading = true;
});
// here you need to make the login user function back a bool value either true or false true for success false for failed
final result = await Provider.of<Authorization>(context, listen: false)
.loginUser(
_emailController.text.trim(),
_passwordController.text.trim(),
)
// hide the loading
setState(() {
_isLoading = false;
});
// check if the result back from the function is true we success
if(result == true){
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => const HomeScreen()),
),
);
}
// else we failed
else{
const snackBar = SnackBar(
backgroundColor: Colors.red,
content: Text("An error occured please try again."),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
}
this answer i think will work perfectly with you you just need to make the login user function return a Future and if success return true or if it failed return false and every thing will work successfully
thanks and i hope this answer helps you
I have a loading spinner that I would like to turn off if the user cancels the purchase using RevenueCat inside of flutter.
I have a try catch block that I use to make the purchase but the error block is never initiated because the try block is always successful.
Here is the code:
purchase(BuildContext ctx, PaymentPlanType selectedPlanType) async {
final offerings = await PurchaseApi.fetchOffers();
try {
if (selectedPlanType == PaymentPlanType.weekly) {
await PurchaseApi.purchasePackage(offerings[0].availablePackages[0]);
} else if (selectedPlanType == PaymentPlanType.monthly) {
await PurchaseApi.purchasePackage(offerings[0].availablePackages[1]);
} else if (selectedPlanType == PaymentPlanType.yearly) {
await PurchaseApi.purchasePackage(offerings[0].availablePackages[2]);
}
} on PlatformException catch (e) {
var errorCode = PurchasesErrorHelper.getErrorCode(e);
if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
showDialog(
context: ctx,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text(e.toString()),
actions: [
ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('OK'))
],
);
});
}
}
}
How do I just catch that error so I can change an isLoading bool to false?
I try to use https://pub.dev/packages/loading_overlay to display a simple loading overlay while making an async call in form.
class AccountFormState extends State<AccountForm> {
bool _loading = false;
override
Widget build(BuildContext context) {
return LoadingOverlay(
child: Form(
...
),
isLoading: _loading,
);
where in the form there is a
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
bool loginResult = await webService.testLoginSite(); // an async call
print('loginResult = $loginResult');
if (loginResult == true) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('successfull')));
}
}
},
child: Text('Check login'),
),
The problem is that the LoadingOverlay does not show overlay loading indicatow while making an async call in the ElevatedButton.
Why does it not work?
You need to setState _isLoading before and after webService.testLoginSite()
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() {
_isLoading = true;
});
bool loginResult = await webService.testLoginSite(); // an async call
print('loginResult = $loginResult');
setState(() {
_isLoading = false;
});
if (loginResult == true) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('successfull')));
}
}
},
child: Text('Check login'),
),
I am new with Flutter and I am having a problem. I'm using mobx. In my view I have a button and inside of this button, I am waiting for the showDialog property to change in order to show the dialog view . However, within onpress the showdialog does not work. Is there any other way to do this?
My controller
#observable
bool showDialog = false;
#action
Future callLoginService() async {
await Future.delayed(Duration(seconds: 6));
showDialog = true;
}
view
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
controller.callLoginService();
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),
This is because your onPressed method is asynchronous but you haven't used 'await' keyword ahead of controller.callLoginService().
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
await controller.callLoginService(); //put await for calling asynchronous methods
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),
I am trying to put an if statement inside another if inside an insitstate in flutter app as I did it but It did't do what it is supposed to do like if the initstate focused on being a function instead of being an initstate here is my code :
#override
void initState() {
super.initState();
FirebaseAuth.instance.currentUser().then((res) {
print(res);
if (res != null) {
if (userType == 'Student') {
Navigator.pushReplacementNamed(context, '/StudentsPage');
} else if (userType == 'Teacher') {
Navigator.pushReplacementNamed(context, '/TeacherPage');
} else if (userType == 'Admin') {
Navigator.pushReplacementNamed(context, '/AdminPage');
}
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Error"),
content: Text('Error In Validating Your Account.'),
actions: [
FlatButton(
child: Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
}
});
}
It is supposed to get the firebase user which it did but It doesn't do auto login when I do restart which it happens by deleting the second if and only doing one Navigation without controlling it, So any Ideas what is the proplem, because I reached a dead end XD.
Where I assign a val to userType 'Which is working as I printed Its val':
void getUserData() async {
try {
firestoreInstance
.collection('Users')
.document(usernameController.text)
.get()
.then((value) {
setState(() {
email = (value.data)['email'];
password = (value.data)['password'];
gender = (value.data)['gender'];
username = (value.data)['username'];
userType = (value.data)['userType'];
});
print('$userType');
});
} catch (e) {
print(e.toString);
}
}