I am unsure if this question has been asked before, but I was unable to find an answer to it.
I have a stateful widget for my signin page, which uses the flutter_toast package for error handling (incorrect password, email already in use, etc.). When using flutter_toast, in order to make a custom toast, I have to use the initState function of the signin page. I also have another class, in a separate file, in which I am trying to move all of my Firebase Auth services into (this is where I am needing to call the showToast function, which is declared in the SigninState class). I have been having trouble figuring out how to get the showToast function to be defined in the AuthService class, so that I will be able to call it there.
Here is my Signin stateful widget class:
class Signin extends StatefulWidget {
const Signin({Key? key}) : super(key: key);
@override
_SigninState createState() => _SigninState();
}
class _SigninState extends State<Signin> {
FToast? fToast;
AuthService authService = AuthService();
@override
void initState() {
super.initState();
fToast = FToast();
fToast!.init(context);
}
...
// build function{
// in here, I call "authService.signInAction()", which needs to call "showToast()"
// }
...
}
showToast(String msg, context) {
bool smallPhone = false;
double width = MediaQuery.of(context).size.width;
if (width <= 370) smallPhone = true;
Widget toast = Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.redAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
width: 10.0,
),
Text(
msg,
style:
TextStyle(fontSize: smallPhone ? 13 : 15, color: Colors.white),
),
],
),
);
fToast!.showToast(
child: toast,
gravity: ToastGravity.CENTER,
toastDuration: const Duration(seconds: 2),
);
}
...
...
} // closing tag for _SigninState class
Here is my AuthService class:
class AuthService {
FirebaseAuth auth = FirebaseAuth.instance;
Signin signin = const Signin();
UserModel _userFromFirebaseUser(User user) {
return UserModel(id: user.uid);
}
Stream<UserModel> get user {
return auth.authStateChanges().map((user) => _userFromFirebaseUser(user!));
}
Future signInAction(
String email, String password, BuildContext context) async {
try {
User user = (await auth.signInWithEmailAndPassword(
email: email, password: password)) as User;
_userFromFirebaseUser(user);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const MyHomePage(title: "Twitter")),
);
} on FirebaseAuthException catch (e) {
if (e.code == 'wrong-password') {
signin.showToast("The password provided is incorrect.", context); // <-- This does not work
} else if (e.code == 'user-not-found') {
signin.showToast("An account with that email does not exist.", context); // <-- This does not work
}
} catch (e) {
signin.showToast("An unexpected error has occurred.", context); // <-- This does not work
}
}
}
This is the error that I am getting:
The method 'showToast' isn't defined for the type 'Signin'.
Try correcting the name to the name of an existing method, or defining a method named 'showToast'
CodePudding user response:
it may possible but you can easy different make it instead of your approach. set a static String message = "";
and..
on FirebaseAuthException catch (e) {
if (e.code == 'wrong-password') {
message = "The password provided is incorrect.";
}
finally you can use it in Auth button..
showToast() {
bool smallPhone = false;
double width = MediaQuery.of(context).size.width;
if (width <= 370) smallPhone = true;
Widget toast = Container(
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.redAccent,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
width: 10.0,
),
Text(
AuthService.message,
style:
TextStyle(fontSize: smallPhone ? 13 : 15, color: Colors.white),
),
],
),
);
maybe it will help
CodePudding user response:
You can use callback but i don't think this is an elegant solution.
signInAction(
String email, String password, {required void Function(String message) one rror}) async {
try {
User user = (await auth.signInWithEmailAndPassword(
email: email, password: password)) as User;
_userFromFirebaseUser(user);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const MyHomePage(title: "Twitter")),
);
} on FirebaseAuthException catch (e) {
if (e.code == 'wrong-password') {
one rror("The password provided is incorrect.");
} else if (e.code == 'user-not-found') {
one rror("An account with that email does not exist.");
}
} catch (e) {
one rror("An unexpected error has occurred.");
}
}
and then you can call
authService.signInAction(email, password,
one rror:(message){
showToast(message, context);
}
)