I did the authentication, but when I click to create an account it throws an error:
MissingPluginException(No implementation found for method createUserWithEmailAndPassword on channel plugins.flutter.io/firebase_auth)
final _auth = FirebaseAuth.instance;
void _submitAuthForm(String email, String user, String pass, bool isLogin , context) async {
AuthResult authResult;
try {
if (isLogin) {
authResult = await _auth.signInWithEmailAndPassword(
email: email, password: pass);
} else {
authResult = await _auth.createUserWithEmailAndPassword(
email: email, password: pass);
}
} on PlatformException catch (err) {
var errorMessage = 'An error ocurred. Please check your credentials.';
if (err.message != null) {
errorMessage = err.message!;
}
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text(errorMessage),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'),
),
],
),
);
} catch (error) {
print(error);
}
}
Make sure you have enabled Sign-in with Email/Password in Firebase Console.
Also, try updating packages to the latest version. Along with that do upgrade your flutter version as well.
Once you did all that, try running flutter clean and re-running your project.
Cheers!! Hope it works.
Solution:
stop the app
run the app again
Hope it helps!
Related
I'm working on authentication part of my flutter project. I want to carryout out exception handling for login when the phone is not connected to internet. The app has 3 auth providers: Phone, GoogleSignIn, and email. The error message is displayed properly for phone signin and email sigin using FirebaseException, which displays the error message. But for GoogleSignIn, if the device is not connected to the internet the code fails at :
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
Since the execution fails at this point I think FirebaseAuthException doesnt work as it is not supported in googleSignIn.
For which FirebaseAuthException doesnt work, but only "Exception" works.
And i dont get the proper error message using Exception in an alert Dialog.
Code for Email SignIn with exception handling.
Future<void> signInWithEmailAndPassword(
String email,
String password,
void Function(FirebaseAuthException e) errorCallback,
) async {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
} on FirebaseAuthException catch (e) {
errorCallback(e);
}
}
Error Dialog which gets called in errorCallback(e)
void _showErrorDialog(BuildContext context, String title, Exception e) {
showDialog<void>(
context: context,
builder: (context) {
return AlertDialog(
title: Text(
title,
style: const TextStyle(fontSize: 24),
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'${(e as dynamic).message}',
style: const TextStyle(fontSize: 18),
),
],
),
),
actions: <Widget>[
ElevatedButton(onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK',
style: TextStyle(color: Colors.deepPurple),
),)
],
);
},
);
}
Exception handling using FirebaseAuthException for email
Exception handling using FirebaseAuthException for email
Google SignIn
Future<void> signInWithGoogle (
void Function(Exception e) errorCallback,
) async {
try{
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication? googleAuth = await googleUser!.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth!.accessToken,
idToken: googleAuth.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
}
on Exception catch (e) {
print(e);
errorCallback(e);
}
}
Exception handling for google login using Exception instead of FirebaseAuthException
Error printed in console
I/flutter ( 4383): PlatformException(network_error,com.google.android.gms.common.api.ApiException: 7: , null, null)
P.S I just want the proper network error to be displayed in the alert dialog and not " com.google.android.gms.common.api.ApiException: 7"
Update
Since FirebaseAuthException isn't called as execution fails at GoogleSignIn, FirebaseAuthException cannot be used.
While the error printed in log is a PlatformException, we can use PlatformException instead of Exception in the try catch block and check the error code since its supported by PlatformException.
The error code can be compared with GoogleSignIn.kNetworkError and GoogleSignIn.kSignInFailedError.
Future<void> signInWithGoogle (
void Function(String errorMessage) errorCallback,
) async {
try {
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
final GoogleSignInAuthentication? googleAuth = await googleUser!.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth!.accessToken,
idToken: googleAuth.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
}
on PlatformException catch (e) {
if (e.code == GoogleSignIn.kNetworkError) {
String errorMessage = "A network error (such as timeout, interrupted connection or unreachable host) has occurred.";
errorCallback(errorMessage);
} else {
String errorMessage = "Something went wrong.";
errorCallback(errorMessage);
}
}
}
Screenshot
If I try to fill TextFormFields responsible for email and password and submit, the login procedure gonna be success always.. no matter if user is in firebase authentication field. I've done login and register pages before with firebase working perfectly. Only diffrence was using pushNamed instead pushReplace. Should it do difference?
That's form inkwell onTap :
onTap: () {
final formState = _formkey.currentState;
if (formState.validate()) {
formState.save();
signIn(_email, _password).whenComplete(
() => Navigator.of(context)
.pushReplacement(
MaterialPageRoute(
builder: (context) =>
HomePage(),
)));
}
}
and authentication:
FirebaseAuth _auth = FirebaseAuth.instance;
Future<void> signIn(String _email, String _password) async {
try {
UserCredential user = await _auth.signInWithEmailAndPassword(
email: _email, password: _password);
} on FirebaseAuthException catch (e) {
print('error');
}
}
Email/password sign-in method is turn on.
How to fix this problem and allow to log in only users that exist in firebase?
I wrote a function for creating accounts in Firebase two months ago and it worked, now when I try to create an account it gives me the next error message:
I/BiChannelGoogleApi(19700): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq#94e857b
The function that I created for doing that stuff is the next one:
Future<void> register() async {
final formState = _formKey.currentState;
if (formState.validate()) {
formState.save();
print('$_email si $_password');
try {
FirebaseUser user = (await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: _email.trim(), password: _password, ))
.user;
user.sendEmailVerification();
presentError("Now you own an account", context);
await Future.delayed(Duration(seconds: 1));
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => LoginPageState(title: 'LoginPage')));
} catch (e) {
print(e);}
Maybe you don't have updated your FirebaseAuth Rules and the unsafe period is over.
See https://firebase.google.com/docs/rules/rules-and-auth
Hello I'm trying to find out how to implement alerts when users are trying to login or signup to my app.
The below code is my "auth-service-dart' page and I am trying to display the message error that shows in the console from (print(e)) per the code below to my signup page where I have the signup button, so the result I want is the app shows alerts if the users make errors like adding an email that was already added or wrong email.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class AuthService {
static final _auth = FirebaseAuth.instance;
static final _firestore = Firestore.instance;
static void signUpUser(
BuildContext context, String name, String email, String password) async {
try {
AuthResult authResult = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
FirebaseUser signedInUser = authResult.user;
if (signedInUser != null) {
_firestore.collection('/users').document(signedInUser.uid).setData({
'name': name,
'email': email,
'profileImageUrl': '',
});
Navigator.pushReplacementNamed(context, signedInUser.uid);
//Provider.of<UserData>(context).currentUserId = signedInUser.uid;
//Navigator.pop(context);
}
} catch (e) {
print(e);
}
}
static void logout() {
_auth.signOut();
//Navigator.pushReplacementNamed(context, LoginScreen.id);
}
static void login(String email, String password) async {
try {
await _auth.signInWithEmailAndPassword(email: email, password: password);
} catch (e) {
print(e);
}
}
}
you can use the showDialog provided by flutter;
here is a simple code for that in your widget
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Error happend'),
content: Text(// your errro code here),
actions: <Widget>[
MaterialButton(
onPressed: () {
Navigator.of(context).pop();
},
color: Theme.of(context).primaryColor,
child: Text(language['ok']),
),
],
);
},
);
In my app, after authentication, user can move to the next screen.
signUpWithEmail().then((user) {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return HomePage();
}));
}).catchError((error) {
print("THE ERROR : $error");
});
Now signUpWithEmail may fail for various reasons like : invalid e-mail, internet connectivity failure and so on. How can I detect those errors and prevent navigation? Here is signUpWithEmail() method:
Future<FirebaseUser> signUpWithEmail() async {
String email = emailControlller.text;
String password = passwordControlller.text;
FirebaseUser user = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: emailControlller.text,
password: passwordControlller.text,
)
.then((user) {
// set balance to 0
Firestore.instance
.collection("users")
.document(user.uid)
.setData({"cash": 0});
}).catchError((e) => print("error : $e"));
return user;
}
You is returning to signUpWithEmail() of anyway, you don't throw the error, so it never will enter on
.catchError((error) {
print("THE ERROR : $error");
})
To fix it you must throw the error on your signUpWithEmail(). Try something like it.
Future<FirebaseUser> signUpWithEmail() async {
String email = emailControlller.text;
String password = passwordControlller.text;
FirebaseUser user = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: emailControlller.text,
password: passwordControlller.text,
)
.then((user) {
// set balance to 0
Firestore.instance
.collection("users")
.document(user.uid)
.setData({"cash": 0});
}).catchError((e) => {
print("error : $e")
throw("Your error") // It return to catch
});
return user;
}
Let me know if you can make it.
Use FutureBuilder widget and wrap the logic in the builder method