Flutter user registration storing data - firebase

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())
],
);
});

Related

How to find Firebase document field and delete document

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!!

How to platform exception error flutter 2020

I am trying to get to get a dialog pop to indicate to the user that the email already exists, but I keep getting this error an the dialog pop doesn't show, have gone through similar solution but none seem to work any help will be appreciated
Exception has occurred.
FirebaseAuthException ([firebase_auth/email-already-in-use] The email address is already in use by another account.)
Below is my authentication code
void registerToFb() {
firebaseAuth
.createUserWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.then((result) {
dbRef.child(result.user.uid).set({
"email": emailController.text,
"age": ageController.text,
"name": nameController.text
}).then((res) {
isLoading = false;
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => Home(uid: result.user.uid)),
);
});
}).catchError((err) {
print(err);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Error"),
content: Text(err.message),
actions: [
FlatButton(
child: Text("Ok"),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
});
}
I've not checked the latest docs but I think the error codes have changed. First check by printing what's inside err.message. I read somewhere this changed to err.code!

Flutter Firebase updated display name successfully but still can't access. It is null

display name of firebase user is updated but still the getter was called on 'null'.
I registered with email and password.
The function used for registering is....
void _registerAccount() async {
final User user = (await _auth.createUserWithEmailAndPassword(
email: emailC.text,
password: passwordC.text,
))
.user;
if (user != null) {
if (!user.emailVerified) {
await user.sendEmailVerification();
}
await user.updateProfile(displayName: usernameC.text);
final user1 = _auth.currentUser;
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => Home(
user: user1,
username: usernameC.text,
)));
} else {
bool _isSuccess = false;
}
}
passwordC,usernameC and emailC are the controllers.
After, signing up I wanted to show 'Display name' on the screen. but I tried to print it and see first, it showed null.
This is my build method of homepage...
#override
Widget build(BuildContext context) {
initialize();
print('Reached here');
print(widget.user.displayName);
return Scaffold(
body: Center(
child: Container(
child: Column(
children: [
Text(''),
Center(
child: RaisedButton(
child: Text("Logout"),
onPressed: () {
FirebaseAuth.instance.signOut();
}),
),
],
)),
),
bottomNavigationBar: BottomNavigationBar(
onTap: (index) {
setState(() {
currentindex = index;
});
},
currentIndex: currentindex,
items: [
BottomNavigationBarItem(
title: Text("Home"), icon: Icon(Icons.account_balance_wallet)),
BottomNavigationBarItem(
title: Text("Home"), icon: Icon(Icons.search)),
BottomNavigationBarItem(
title: Text("Home"), icon: Icon(Icons.account_circle)),
]),
);
initialize method here is to call these two methods
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
initialize method cannot be problem anyway.
Thank you.
FirebaseAuth.currentUser() will only detect changes made locally to the user, but if any server-side changes occur, it won't detect them, unless FirebaseUser.reload() is called first so you have to call
await user.reload();
after the update() is called.

Flutter FirebaseAuth not sending verification code to phone

I'm trying to add a feature on my app that allows users to verify their phone number by sending a code to their phone numbers. I found that I can do that by using firebase. This is how I send verification code:
Future<void> verifyPhone() async {
void verificationCompleted(AuthCredential phoneAuthCredential) {
print('verificationCompleted $phoneAuthCredential');
_phoneAuthCredential = phoneAuthCredential;
_db.updateUserField(userUid, {
'isNumberConfirmed': true,
'linkedAccounts': FieldValue.arrayUnion(['P-$phoneAuthCredential'])
});
currentUser.isNumberConfirmed = true;
currentUser.linkedAccounts.add('P-$phoneAuthCredential');
worked = true;
}
void verificationFailed(FirebaseAuthException error) {
worked = false;
}
void codeSent(String verificationId, [int code]) {
_code = code;
_verificationId = verificationId;
print('Code: $code\t_verificationId: $_verificationId');
}
void codeAutoRetrievalTimeout(String verificationId) {
worked = false;
}
_auth.verifyPhoneNumber(
phoneNumber: '+1${currentUser.phone}',
timeout: Duration(milliseconds: 60000),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
}
but whenever this method get called, I get the following messages and no verification code is sent:
I/BiChannelGoogleApi(25924): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzao#bafccce
W/DynamiteModule(25924): Local module descriptor class for com.google.firebase.auth not found.
I/FirebaseAuth(25924): [FirebaseAuth:] Preparing to create service connection to gms implementation
I'm not sure why it is not sending the code. Am I missing something?
I find your code hard to debug so I am sharing this :
First make sure you have enabled phone sign in method in firebase console ,
and added Firebase Authentication plugin and Firebase core plugin in pubspec.yaml
define your verify phone number button like this :
onPressed: (){
//code for sign in
final mobile = _phoneTextBoxController.text.trim();
registerUser(mobile, context);
}
Now define whole verifying process like this :
Future registerUser(String mobile, BuildContext context) async{
FirebaseAuth _auth = FirebaseAuth.instance;
_auth.verifyPhoneNumber(
phoneNumber: mobile,
timeout: Duration(seconds: 60),
verificationCompleted: (AuthCredential authCredential){
_auth.signInWithCredential(_credential).then((AuthResult result){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => HomeScreen(result.user)
));
}).catchError((e){
print(e);
});
},
verificationFailed: (AuthException authException){
print(authException.message);
},
codeSent:(String verificationId, [int forceResendingToken]){
//show dialog to take input from the user
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: Text("Enter SMS Code"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _codeController,
),
],
),
actions: <Widget>[
FlatButton(
child: Text("Done"),
textColor: Colors.white,
color: Colors.redAccent,
onPressed: () {
FirebaseAuth auth = FirebaseAuth.instance;
smsCode = _codeController.text.trim();
_credential = PhoneAuthProvider.getCredential(verificationId: verificationId, smsCode: smsCode);
auth.signInWithCredential(_credential).then((AuthResult result){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => HomeScreen(result.user)
));
}).catchError((e){
print(e);
});
},
)
],
)
);
},
codeAutoRetrievalTimeout: (String verificationId){
verificationId = verificationId;
print(verificationId);
print("Timout");
}
);
So what above code does ? First it sends the OTP code to user and try to sign in using this code :
verificationCompleted: (AuthCredential authCredential){
_auth.signInWithCredential(_credential).then((AuthResult result){
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) => HomeScreen(result.user)
));
}).catchError((e){
print(e);
});
},
and pushes user to the home screen , you can change above code accordingly to match your app home screen . If auto retrieval fails then the codeSent : shows user a showDialog to manually enter the code . For more information visit this medium article and for complete code visit this github repository

Firebase Phone auth is not verifying the OTP entered

I am trying to integrate phone authentication system in my flutter app. But even when I enter a wrong OTP the user gets verified and enters into the next page.
I am using Dialog box to ask for OTP
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new AlertDialog(
title: Text('Enter sms Code'),
content: TextFormField(
controller: _smsController,
keyboardType: TextInputType.number,
textInputAction: TextInputAction.done,
decoration: InputDecoration(
hintText: 'Enter OTP', icon: Icon(Icons.perm_phone_msg)),
maxLength: 6,
maxLengthEnforced: true,
),
contentPadding: EdgeInsets.all(10.0),
actions: <Widget>[
new RaisedButton(
child: Text('Login'),
textColor: Colors.white,
onPressed: () {
_signInWithPhoneNumber(context);
})
],
);
});```
```void _signInWithPhoneNumber(BuildContext context) async {
final AuthCredential credential = await PhoneAuthProvider.getCredential(
verificationId: _verificationId,
smsCode: _smsController.text,
);
await _auth
.signInWithCredential(credential)
.then((FirebaseUser user) async {
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InfoScreen(_phoneNumberController.text)));
}).catchError((e) {
print(e.message);
Navigator.of(context).pop();
});
}
}```
You have to get same of auth to verify a OTP of firebase admin as explained here.
You have done the mistake with the PhoneAuthProvider
final AuthCredential credential = await PhoneAuthProvider.getCredential(
verificationId: _verificationId,
smsCode: _smsController.text,
);
Replace above code with this:
FirebaseAuth.instance
.signInWithPhoneNumber(verificationId: verificationId, smsCode: smsCode)
.then((user) {
Navigator.of(context).pushReplacementNamed('/homepage');
}).catchError((e) {
print(e);
});
Using this you can verify the phone with code. For more details please visit Here
I think you have to add an onCompleteListener by changing the ".then(FirebaseUser ...)" to ".addOnCompleteListener(this, new OnCompleteListener(AuthResult res) {});"
The AuthResult object has a boolean "isSuccessful()" which you can check to make sure the user entered the correct code.
I assume that Firebase returns the FirebaseUser object no matter if the code actually matches.

Resources