I have a button that lets a user delete their account. When users signup their email and name is saved to a Firestore collection called users, I want to search in the collection's documents where the uid field is equal to the current user uid then delete that document. Deleting the account works but not the document and I'm not getting any errors, I'm not sure what I'm doing wrong...
CollectionReference users = FirebaseFirestore.instance.collection('users');
TextButton(
onPressed: () async {
try {
await users
.where('uid', isEqualTo: _auth.currentUser!.uid).firestore.doc(users.doc().path).delete();
await _auth.currentUser!.delete().then((value) =>
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => const WelcomeScreen())));
} on FirebaseAuthException catch (error) {
Fluttertoast.showToast( msg: error.message.toString(),
gravity: ToastGravity.TOP,
backgroundColor: Colors.red,
textColor: Colors.white);
} on FirebaseException catch (error) { Fluttertoast.showToast(
msg: error.message.toString(),
gravity: ToastGravity.TOP,
backgroundColor: Colors.red,
textColor: Colors.white);
}
},
child: const Text( 'Delete', style: TextStyle(color: Colors.red),
))
I got the problem I was just working on my app and found a similar code so here is the solution. Just declare user id as variable for ease not necessary (optional) like this
final uid = _auth.currentUser!.uid; //optional
& then use this in your code:-
await users.doc(uid).delete();
instead of
await users
.where('uid', isEqualTo: _auth.currentUser!.uid).firestore.doc(users.doc().path).delete();
and Boom now it works like an charm!!
Hope this works!!
Related
Here is what I'm doing in my code.
ReusableButton(
title: "Login",
color: Colors.white,
onPress: () async {
try {
final user = await _auth.signInWithEmailAndPassword(
email: myEmailController.text,
password: myPasswordController.text,
);
if (user != null) {
await Navigator.pushNamed(context, AllTasks.id);
}
} catch (e) {
String newString = e.toString().split("]").removeLast();
setState(() {
showDialog(
context: context,
builder: (value) => AlertDialog(
title: Text(
"Wrong Information",
style: kNormalTextStyle,
),
content: Text(
newString,
),
actions: [
FlatButton(
onPressed: () {
Navigator.of(value).pop();
},
child: Text(
"Close",
style: kNormalTextStyle,
))
],
));
});
}
},
),
I'm trying to login and after that pushin the page to another page. However this login part is a little bit slow so I get an error like this:
I'm assuming this is about the connection speed with firebase but is there a solution to solve this? Btw, when I reload the code, it starts working.
Here is my AllTasks code block:
https://github.com/sonelektrikci/task_manager_app_flutter/blob/main/task_management_app_flutter/lib/screens/all_tasks.dart
I'm pushing the page to here when user logs in.
This is most likely causing your issue:
.where('email', isEqualTo: loggedInUser!.email)
How are you asserting that the user is indeed logged in and promising your compiler that an email is retrievable? This is the explanation of your error.
Refactor your code, in a way to not make it into this block, unless loggedInUser is not null.
I've perused the forums, google, and youtube for info on writing data to a real-time database with flutter and haven't found a proper guide for even the most basic write.
That being said, in my app, I am currently trying to save the user's email to the database as a child of the user's new id. I am attempting to do this immediately after calling .createUserWithEmailAndPassword. This all should occur on click of a Material Button. I previously had the write inside of the then statement, but that was giving me an error.
Code:
FirebaseAuth userAuth = FirebaseAuth.instance;
void saveEmailInDb(String userId, String email) {
final userRef = FirebaseDatabase.instance.reference();
userRef.child(userId).child("Email").push().set(email);
}
//inside of the build widget
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32),
),
color: colorPalette.chooseColor('yellow'),
child: Container(
padding: EdgeInsets.all(13),
child: Text(
'Register',
style: GoogleFonts.ubuntu(
color: colorPalette.chooseColor('darkGrey'),
fontSize: 17),
),
),
onPressed: () async {
try {
UserCredential userCredential = await userAuth
.createUserWithEmailAndPassword(
email: tecEmail.text,
password: tecPassword.text)
.then(
(value) => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoadingPage(),
),
),
);
saveEmailInDb(
userCredential.user.uid, tecEmail.text);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
},
),
I have instantiated firebase in the main widget:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
GetMaterialApp(
home: LoadingPage(),
),
);
}
Now, I know that flutter is hooked up properly to my app because an account is created in the firebase console under authentication. However, nothing is written to the database and as there are no proper guides or official documentation, I am unsure how to proceed.
Database Rules:
{
"rules": {
".read": true,
".write": true
}
}
Answer: Moving the navigation code outside of the then statement, and below the database write, was sufficient to solve this problem. Basically, the navigation was poping the widget before the database code was called. Revised code below:
MaterialButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32),
),
color: colorPalette.chooseColor('yellow'),
child: Container(
padding: EdgeInsets.all(13),
child: Text(
'Register',
style: GoogleFonts.ubuntu(
color: colorPalette.chooseColor('darkGrey'),
fontSize: 17),
),
),
onPressed: () async {
try {
UserCredential userCredential =
await userAuth.createUserWithEmailAndPassword(
email: tecEmail.text,
password: tecPassword.text);
saveEmailInDb(userCredential.user.uid, tecEmail.text);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoadingPage(),
),
);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print('The account already exists for that email.');
}
} catch (e) {
print(e);
}
},
),
I can authenticate users just fine, however, when I purposely enter an email address that doesn't exist or a proper email address, but wrong password, there seems to be a delay in the authentication error message.
I initially tried it with a Future, async and await inside, but following a udemy tutorial and he didn't use that so I took it away, but no difference in how it ran. The one thing different I'm doing than in the tutorial is I'm also updating a cloudstore database.
loginUser(_email, _password) {
formkey.currentState.save();
if (formkey.currentState.validate()) {
_auth
.signInWithEmailAndPassword(email: _email, password: _password)
.catchError((e) {
Fluttertoast.showToast(
msg: e.message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
timeInSecForIos: 5,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}).then((newUser) {
var now = new DateTime.now();
Firestore.instance
.collection('users')
.document(newUser.uid)
.collection('userInfo')
.document('userInfo')
.setData({
'Last login': now,
})
.then((onValue) {
print('Created it in sub collection');
}).catchError((e) {
print('======Error======== ' + e);
});
getSignedInUser();
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyApp()),
);
});
}
}
getSignedInUser() async {
mCurrentUser = await _auth.currentUser();
DocumentSnapshot result = await Firestore.instance.collection('users')
.document(mCurrentUser.uid).collection('profile').document('profile')
.get();
String myResult = result['First Name'];
Fluttertoast.showToast(
msg: "Welcome $myResult!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.TOP,
timeInSecForIos: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0
);
}
}
My first time I enter an invalid email, I get errors in the console stating the line where e.message is called on null. if i press login again, it gives me the proper error message. Now if I put the right email address, but wrong password (in the same running instance). it says username doesn't exist. If I click it again, it gives me proper invalid password message. Any ideas what I'm doing wrong? Thanks in advance
Is there a way I can get data from firebase and store it as string for example in flutter?
I want my app to have role based users each user has a role and a page for them.
firebase authentication only has username and password. in my database I have Users collection the UID is used as an ID for the documents, I want to query the document and get the role value and store it in a variable as string.
http://prntscr.com/kwcylt
Container(
height: 50.0,
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.greenAccent,
color: Colors.green,
elevation: 7.0,
child: GestureDetector(
onTap: () {
FirebaseAuth.instance
.signInWithEmailAndPassword(
email: email,
password: password)
.then((FirebaseUser user) {
var userRole = Firestore.instance.collection('Users').document(user.uid).toString();
if(userRole['Role'].toString().compareTo("Admin"))
Navigator.of(context).pushReplacementNamed('/AdminTabs');
else Navigator.of(context).pushReplacementNamed('/UserTabs');
})
.catchError((e) {
print(e);
});
},
I want userRole Contain data from firebase
Update Your Code like this , it will Work: You are Basically Running the Check on Document Reference instead of Document Snapshot.
.then((FirebaseUser user) {
Firestore.instance.collection('Users')
.document('user.uid').get().then((userRole){
if(userRole['Role'].toString().contains("Admin")){
Navigator.of(context).pushReplacementNamed('/AdminTabs');
}
else {Navigator.of(context).pushReplacementNamed('/UserTabs');}
});
})
.catchError((e) {
print(e);
});
},
I'm new to flutter. I need some help with Registering users with my app. I'm using Firebase authentication just to get the email and I need to save the details of the users in a database. I'm trying with cloud firestore, but I'm feeling like its not the best ideal option. And when login I want verify if the user is registered or not
you can use this code for registration user in Cloud Firestore
final FirebaseAuth _auth = FirebaseAuth.instance;
_auth
.createUserWithEmailAndPassword(
email: _myEmail, password: _myPassword)
.catchError((e) {
showDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text('Error Occured'),
content: Text(e.toString()),
actions: <Widget>[
CupertinoButton(
child: Text('Ok'),
onPressed: () => Navigator.of(context).pop())
],
);
});
FirebaseAuth.instance
.signInWithEmailAndPassword(email: _myEmail, password: _myPassword)
.catchError((e) {
showDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text('Error Occured'),
content: Text(e.toString()),
actions: <Widget>[
CupertinoButton(
child: Text('Ok'),
onPressed: () => Navigator.of(context).pop())
],
);
});