How to show the error message when the user enters the incorrect username and password? Can I display a message when there are multiple conditions in authenticating the user? The message should show on the screen instead of throwing the exception in the console.
The exception I get in the console
The exception has occurred.
PlatformException (PlatformException(firebase_auth, com.google.firebase.auth.FirebaseAuthInvalidUserException: There is no user record corresponding to this identifier. The user may have been deleted., {code: user-not-found, additionalData: {}, message: There is no user record corresponding to this identifier. The user may have been deleted.}, null))
import 'package:firebase_auth/firebase_auth.dart';
abstract class BaseAuth {
Future<String> currentUser();
Future<String> signIn(String email, String password);
Future<String> createUser(String email, String password);
Future<void> signOut();
}
class Auth implements BaseAuth {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Future<String> signIn(String email, String password) async {
UserCredential result = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
User user = result.user;
return user.uid;
}
Future<String> createUser(String email, String password) async {
UserCredential result = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
User user = result.user;
return user.uid;
}
Future<String> currentUser() async {
User user = _firebaseAuth.currentUser;
return user != null ? user.uid : null;
}
Future<void> signOut() async {
return _firebaseAuth.signOut();
}
}
A simple try catch would do the trick
Future<String> signIn(String email, String password) async {
try{
UserCredential result = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
User user = result.user;
return user.uid;
}on AuthException catch(error){
return Future.error(error);
}
}
Now on how to handle the error in the UI assuming you know the basics :D
await signIn(email,password).then((onSuccess){
//do something with data or not up to you
}).catchError((err){
print(err);
});
Hope it helps :)
Related
My .uid says: The getter 'uid' isn't defined for the type 'UserCredential'.
My Code:
import 'package:firebase_auth/firebase_auth.dart';
class AuthService { final FirebaseAuth _firebaseAuth =
FirebaseAuth.instance;
Stream<String> get onAuthStateChanged =>
_firebaseAuth.authStateChanges().map(
(User user) => user?.uid,
);
Future<String>
createUserWithEmailAndPassword(
String email, String password, String name) async {
final currentUser = await _firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: password,
);
var updateInfo = UserUpdateInfo();
await FirebaseAuth.instance.currentUser.updateProfile(displayName:name);
await FirebaseAuth.instance.currentUser.reload();
return FirebaseAuth.instance.currentUser.uid; }
Future<String>
signInWithEmailAndPassword(
String email, String password) async {
return (await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password))
.uid; }
signOut() {
return _firebaseAuth.signOut(); } }
class UserUpdateInfo { }
How can I fix it? Thanks!
The signInWithEmailAndPassword and createUserWithEmailAndPassword methods return a UserCredential object, which (as the error message says) doesn't have a uid property. To get to the UID from the UserCredential, you do credential.user.uid.
You're looking for:
await (_firebaseAuth.signInWithEmailAndPassword(email: email, password: password)).user.uid
Or a bit more readable when spread over two lines/statements:
var credentials = await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
return credentials.user.uid
I just updated Google Firebase Auth in Flutter app because I was getting some wried SDK errors but now I'm getting
Error: 'currentUser' isn't a function or method and can't be invoked.
var user = await _firebaseAuth.currentUser();
I looked at the migration guide and understand that currentUser() is now synchronous via the currentUser getter. but I'm not sure how I should change my code now to fix this.
My code
class Auth implements BaseAuth {
final auth.FirebaseAuth _firebaseAuth = auth.FirebaseAuth.instance;
#override
Future<String> signIn(String email, String password) async {
var result = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
var user = result.user;
return user.uid;
}
#override
Future<String> signUp(
String email, String password, String name, String company) async {
final userReference = FirebaseDatabase.instance.reference().child('users');
var result = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
var user = result.user;
await userReference
.child(user.uid)
.set(User(user.uid, email, name, company).toJson());
return user.uid;
}
#override
Future<auth.User> getCurrentUser() async {
var user = await _firebaseAuth.currentUser();
return user;
}
#override
Future<void> signOut() async {
return _firebaseAuth.signOut();
}
#override
Future<void> sendEmailVerification() async {
var user = await _firebaseAuth.currentUser();
await user.sendEmailVerification();
}
#override
Future<void> resetPassword(String email) async =>
await _firebaseAuth.sendPasswordResetEmail(email: email);
#override
Future<bool> isEmailVerified() async {
var user = await _firebaseAuth.currentUser();
return user.isEmailVerified;
}
}
It looks like you're using the latest version of the FlutterFire libraries with outdated code.
In previous versions of the libraries, currentUser() was a method, that you had to await. In the latest versions of the library it's a property, and you no longer have to await its result.
So
var user = _firebaseAuth.currentUser;
Also see the documentation on using Firebase Authentication in your Flutter app, specifically the section on monitoring authentication state as it provides a way to listen for updates to the authentication state.
I am getting the above mentioned error when logging in. This exception is raised even after I am ensuring that the isEmailVerified() is called only after checking whether the current user is null or not.
My authentication.dart file looks like below:
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
abstract class BaseAuth {
Future<String> signIn(String email, String password);
Future<String> signUp(String email, String password);
Future<FirebaseUser> getCurrentUser();
Future<void> sendEmailVerification();
Future<void> signOut();
Future<bool> isEmailVerified();
}
class Auth implements BaseAuth {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Future<String> signIn(String email, String password) async {
AuthResult result = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
return user.uid;
}
Future<String> signUp(String email, String password) async {
AuthResult result = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
sendEmailVerification();
return user.uid;
}
Future<FirebaseUser> getCurrentUser() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user;
}
Future<void> signOut() async {
return _firebaseAuth.signOut();
}
Future<void> sendEmailVerification() async {
FirebaseUser user = await _firebaseAuth.currentUser();
user.sendEmailVerification();
}
Future<bool> isEmailVerified() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user.isEmailVerified;
}
}
And inside the LoginPage, I am checking like this:
if(auth.signIn(email, password)!=null)
{
if(auth.getCurrentUser()!=null)
{
if(auth.isEmailVerified() != null) {
Toast.show("Login Successful!", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Route route = MaterialPageRoute(builder: (context) => HomePage());
Navigator.pushReplacement(context, route);
}
}
}
I don't know how to resolve this. Any help is appreciated.
From your Auth class, your methods have future signatures.
You will have to await their results since it will be needed by the other conditions.
You can do:
if((await auth.signIn(email, password))!=null){
if((await auth.getCurrentUser())!=null){
if((await auth.isEmailVerified()) != null) {
Toast.show("Login Successful!", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Route route = MaterialPageRoute(builder: (context) => HomePage());
Navigator.pushReplacement(context, route);
}
}
}
But the snippet above must be placed in within an async method.
Can't add I more user information with await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: _email, password: _password); function?
part of signup.dart file:
String _email, _password, _name;
final formkey = new GlobalKey<FormState>();`
Future<void> registered() async {
if (formkey.currentState.validate()) {
formkey.currentState.save();
try {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: _email, password: _password);
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
Firestore.instance
.collection("users")
.document(firebaseUser.uid)
.setData({"name": _name});
await firebaseUser.reload();
firebaseUser = await FirebaseAuth.instance.currentUser();
print(
"${firebaseUser.uid},${firebaseUser.email},${firebaseUser.displayName} , $_password this user has been created-----");
} catch (e) {
print("${e.message} message--------------------------------------");
}
} else {
print("somthing went wrong");
}
}
I have tried many way to do this but still i have no result
You are saving data in Firestore, and trying to get the name from Firebase Auth. Those are two services. Instead of trying to use firestore, what you could is,
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
var userUpdateInfo = UserUpdateInfo();
userUpdateInfo.displayName = _name;
firebaseUser.updateProfile(userUpdateInfo);
await firebaseUser.reload();
firebaseUser = await FirebaseAuth.instance.currentUser();
After creating the account using the method .createUserWithEmailAndPassword pass the value of the user to another class by
final FirebaseAuth _auth = FirebaseAuth.instance;
//user object based on firebase
User _userFromFirebase(FirebaseUser user){
return user != null ? User(uid: user.uid):null;
}
Future loginWithEmailAndPass(String email,String password)async{
try{
AuthResult result = await _auth.signInWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
return _userFromFirebase(user);
}catch(e){
print(e.toString());
return null;
}
}
Pass the value of user to a new class by creating a new dart file
class User{
final String uid;
User({this.uid});
}
Include that dart file in the home page for the user name.
Refer this tutorial for guidance.
https://youtu.be/Jy82t4IKJSQ?list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC
errors
- Target of URI doesn't exist: 'package:firebase_auth/firebase_auth.dart'.
Try creating the file referenced by the URI, or Try using a URI for a file that does exist.dart(uri_does_not_exist
The name 'FirebaseUser' isn't a type so it can't be used as a type argument.
Try correcting the name to an existing type, or defining a type named 'FirebaseUser'.dart(non_type_as_type_argument)
code:
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
abstract class BaseAuth {
Future<String> signIn(String email, String password);
Future<String> signUp(String email, String password);
Future<FirebaseUser> getCurrentUser();
Future<void> sendEmailVerification();
Future<void> signOut();
Future<bool> isEmailVerified();
}
class Authen implements BaseAuth {
final Auth _firebaseAuth = Auth.instance;
Future<String> signIn(String email, String password) async {
AuthResult result = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
return user.uid;
}
Future<String> signUp(String email, String password) async {
AuthResult result = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
return user.uid;
}
Future<FirebaseUser> getCurrentUser() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user;
}
Future<void> signOut() async {
return _firebaseAuth.signOut();
}
Future<void> sendEmailVerification() async {
FirebaseUser user = await _firebaseAuth.currentUser();
user.sendEmailVerification();
}
Future<bool> isEmailVerified() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user.isEmailVerified;
}
}
You're getting the first error because the package wasn't properly installed. You can try a few things:
flutter packages get (to use the packages in pubspec.yaml)
restarting your IDE
flutter clean and then flutter run (clears build cache)
flutter packages pub cache repair (pub cache might be corrupted)
The second error will resolve itself once the package is correctly installed. Because 'package:firebase_auth/firebase_auth.dart' doesn't exist, you can't use any classes from that package. FirebaseUser is a class in the firebase_auth package.