Errors in my firebase delete account code in my flutter app - flutter

I have created a delete account page in my Flutter app . And I have written a code for the onPressed function.
My logic: On the delete account page I have added 2 text fields, they are: email and password, when the user enters his email and password and clicks on the Delete Account button, I want firebase to check whether the credentials are correrct. Only if the credentials are correct I want firebase to delete the account.
But I'm getting an error:
The method 'delete' isn't defined for the type 'AuthUser'.
Try correcting the name to the name of an existing method, or defining a method named 'delete'.
onPressed code:
onPressed: () async {
final email = _email.text;
final password = _password.text;
try {
await AuthService.firebase().logIn(
email: email,
password: password,
);
final user = AuthService.firebase().currentUser;
await user?.delete();
} on UserNotFoundAuthException {
await showErrorDialog(
context,
'User not found',
);
} on WrongPasswordAuthException {
await showErrorDialog(
context,
'Wrong credentials',
);
} on GenericAuthException {
await showErrorDialog(
context,
'Authentication error',
);
}

Related

Cloud Firestore Database is not displaying users after authentication?

I am trying to do authentication using createUserWithEmailAndPassword .The user iis getting created since I can signin using the email and password which created using createUserWithEmailAndPassword .But my firestore database is not showing the document which I have created using createUserWithEmailAndPassword().
This is my code:
onPressed: () async {
try {
final newuser = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: email ?? 'error',
password: password ?? 'error',
);
if (newuser != null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => home()),
);
}
} catch (e) {
print(e);
}
I have created 3 users with this method and I'm able to login with these credential but these users are not showing in my Firestore Database.
As #ashish already mentioned, you need to store all your extra parameters in the firestore as documents. A better way to implement this is to use different function to register user and create a user document related to that registered user.
Below is an example I created to help out!
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
void main() {
String email = "test#test.com";
String password = "123456";
String firstName = "test";
String lastName = "test";
String phoneNumber = "09876543456";
/// This is the function to create new user
Future<void> createUser(
email,
password,
firstName,
lastName,
phoneNumber,
/*... and any other params you wish to collect */
) async {
// firebase auth
final FirebaseAuth auth = FirebaseAuth.instance;
// firestore db
FirebaseFirestore db = FirebaseFirestore.instance;
// try-catch creation process to accurate exception
try {
final credential = await auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
// get user id
String userID = credential.user!.uid;
// creating user profile on db
await db.collection("users").doc(userID).set({
"id": userID,
"firstName": firstName,
"lastName": lastName,
"phoneNumber": phoneNumber,
// ... other params
});
print("Signed up successfully!");
} on FirebaseAuthException catch (error) {
print("Something is wrong: $error");
}
}
/// this is the create button
TextButton(
onPressed: () async {
await createUser(
email,
password,
firstName,
lastName,
phoneNumber,
/*... and any other params you wish to collect */
);
},
child: const Text("Create test user"),
);
}
Let me know if you need anything else :). BYE!!!
To store the data in the database you need to use a Firestore instance to store data in firebase Firestore.
onPressed: () async {
try {
final newuser = await FirebaseAuth.instance
.createUserWithEmailAndPassword(
email: email ?? 'error',
password: password ?? 'error',
);
await FirebaseFirestore.instance.collection('Users').doc(newuser!.uid).set({
email: newuser.email
});
if (newuser != null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => home()),
);
}
} catch (e) {
print(e);
}
}
You need to put the data which you want to store in firestore in set() function.
Firebase Authentication data are show into the login into firebase then on tap of Authentication options menu -> user section , you can view store 3 users data in this section

Check if Firebase User is null in Flutter

I'm making a Flutter App and I want to check if the user is registered in the database when he logs in the app.
So basically if he's registered and he logs in with no errors, there will be a loading indicator and he will be redirected to the Homepage.
If he made an error (wrong email/password for example) he will get snackbar displaying the error.
The problem is that I couldn't find the right 'if statement' to check if the user is registered or not.
Here's my Login button :
`
TextButton(
onPressed: () async {
if (_key.currentState!.validate()) {
var email = _emailController.text;
var password = _passwordController.text;
User? user =
(await _auth.login(email, password, context));
user != null
? setState(() => loading = true)
: setState(() => loading = false);
print(loading);
}
},
child: loading
? const CircularProgressIndicator()
: Text('Connect'),
),
`
And the login function :
Future login(String email, password, BuildContext context) async {
try {
User user = (await _auth.signInWithEmailAndPassword(
email: email, password: password))
.user!;
Navigator.pushNamed(context, DiscoverPage.id);
} on FirebaseAuthException catch (error) {
var message = '';
switch (error.code) {
case 'user-not-found':
message = 'User not found';
}
print(error.code);
ScaffoldMessenger.of(context).showSnackBar(
CustomSnackBar(message, context),
);
}
}
'loading' is initiated to false and when I print(loading) it always returns false, no matter if there's an error or not. The setState dont seem to work.
What am I missing here ?
Thanks.
try this:
try {
User user = (await _auth.signInWithEmailAndPassword(
email: email, password: password))
.user!;
if(FirebaseAuth.instance.currentUser != null) {
Navigator.pushNamed(context, DiscoverPage.id);
}
} on ...

Log out button for different type of accounts in flutter firebase Auth

I have a flutter app with multiple sign in options (Email and password, Google account, phone number). Once the user sign in to the application, he will then have a drawer.
There is a Sign out button inside this drawer which should sign the user out when he press it and send him back to the signup page. So I have been using the sign out instance from firebase auth
await FirebaseAuth.instance.signOut();
But since I added the google sign in options I started facing a problem which is that for google sign out, I nee dto disconnect the user first await googleSignIn.disconnect();
So I added this line to the sign out function to be like this:
Future<void> SignOut() async {
await googleSignIn.disconnect();
await FirebaseAuth.instance.signOut();
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (BuildContext context) => AuthPage(),
),
(route) => false,
);}
This button works fine when the user sign in with google but if he signs in with different method then an error will be thrown:
Unhandled Exception: PlatformException(status, Failed to disconnect., null, null)
How can I handle different type of users signout with one button?
Future<void> SignOut() async {
if (googleSignIn.currentUser != null){
await googleSignIn.disconnect();
await FirebaseAuth.instance.signOut();}
else{
await FirebaseAuth.instance.signOut();}

FS Document is not getting created after user is registered

When a user submits their information on the "Signup page", the user should have
an account registered within fire store and
a fire store document created with all of their information inside.
The user account gets registered fine, but the document never gets created. I'm not getting any error messages so I'm trying to use debug prints to find out where things are going wrong.
Debug Prints:
>> login: signUp // this starts the signUp function
>> login: Start hideNewUserOverlay // hide overlay prints before signUp finishes
>> signUp: current user got // the following prints are from signUp
>> signUp: user.id = L8pD6tng5NTAACN7VygK93F6crg1
>> signUp: document creation code Start // then nothing happens after this
Future that is supposed to register the user and create document: // this will eventually pass in first/last names too, that's why I'm using this function
Future<void> signUp(String email, String password) async {
try {
// ignore: unused_local_variable
UserCredential result = await auth.createUserWithEmailAndPassword(email: email, password: password); // <-- user account is created on first press
} catch (e) {
debugPrint('>> Authentication: create new user error');
}
user = auth.currentUser!;
debugPrint('>> signUp: current user got');
String userID = user.uid;
debugPrint('>> signUp: user.id = $userID'); // all debugs print out correctly here, even userID
debugPrint('>> signUp: document creation code Start');
await collectionReference.doc(userID).set({ // code does not run
'userID': userID,
'accountCreated': DateTime.now(),
'email': email,
});
debugPrint('>> Authentication: User Document Created');
}
Signup page:
onPressed: () {
debugPrint('>> login: signUp');
signUp(_email, _password); // this line should finish before the next debug statement is printed but it does not
debugPrint('>> login: Start hideNewUserOverlay'); // prints before signUp() is done
hideNewUserOverlay(); // this will close the Signup page
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const Nav(),
));
}
At the bottom of the code, the document will get created if I route to a different class. Nav() >> Verify(). The weird part is that Verify does not take in any user information. Verify() has a timer so maybe that has something to do with it? I think it is because the signup() function does not complete before the overlay is hidden. Maybe Nav() needs init state?
Putting await in from of a statement that returns a Future makes that line block the rest of the execution. It does not however make any other call wait.
If you want to wait until signUp is done, use await there too:
await signUp(_email, _password);
That does mean you'll need to mark onPressed as an async method too.
If that is not an option, you can always use then:
onPressed: () {
debugPrint('>> login: signUp');
signUp(_email, _password).then(() {
debugPrint('>> login: Start hideNewUserOverlay'); // prints before signUp() is done
hideNewUserOverlay(); // this will close the Signup page
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => const Nav(),
));
}
}

flutter: DioError [DioErrorType.response]: Http status error [400]

I created a login form which fetched the credentials from api and is perfectly working. i have two type of users employee and manager. so there are two dashboard. i store their type in database with name Type, when i am getting response of login api, and get the Type value and store it in type varibale and checking if it equal to Employee the will redirect to employee dashboard else manager dashboard.
It was working fine too, i test it 2 to 3 times, but when i run again my app and login as employee it redirect me to employee dashboard but when i try to login as manager it sending me this dio 400 error.
i did debugging too, i am getting values too in body parameters and on data too, but after that it prints 400 error.
when i run login api on postman and passing manager credentials it working perfectly their too.
here is my login funtion
Future login() async {
Dio dio=new Dio();
var data={
'username': user.username,
'password': user.password,
'date':formattedDate
};
await dio
.post(localhostUrlLogin,data: json.encode(data)) // it prints error after this line
.then((onResponse) async {
SharedPreferences myPrefs=await SharedPreferences.getInstance();
print(onResponse.data);
print(onResponse.statusCode);
String type=onResponse.data['User']['Type'];
print(type);
if(type=='Employee')
{
Navigator.push(
context, new MaterialPageRoute(builder: (context) => Employee()));
}
else if(type=='Manager'){
Navigator.push(
context, new MaterialPageRoute(builder: (context) => Manager()));
}
myPrefs.setString('name',name );
myPrefs.setString('email', email);
myPrefs.setString('designation', designation);
myPrefs.setString('accesstoken', token);
myPrefs.setBool('timeinStatus', timeinstatus);
myPrefs.setString('DOB', dob);
}).catchError((onerror){
print("error "+onerror.toString());
showAlertDialog(context);
});
}
kindly please help, how to fix this.