helllo
I'm trying to make phone auth with flutter
I managed to implement but doens't work in my boss phone (android)
in my phone it works.
that's why I'm almost crazy
I wanna connect boss phone with cable debug mode
but my boss refused to it. ๐ซ๐ซ๐ซ
here's my code
Future createUserWithPhone({String phoneNumber, BuildContext context}) async {
String phoneNumberWith82 = '+82 $phoneNumber';
await fAuth.verifyPhoneNumber(
phoneNumber: phoneNumberWith82,
timeout: Duration(seconds: 60),
verificationCompleted: (AuthCredential authCredential) async {
print('here verificationcompleted');
โ
not a big deal, verificationCompleted doesn't work don't know why
await fAuth
.signInWithCredential(authCredential)
.then((AuthResult result) {
Fluttertoast.showToast(
msg: "success",
backgroundColor: Colors.black26,
textColor: Colors.white,
);
}).catchError((e) {
print('Error Occurs โญ3');
return "error";
});
},
verificationFailed: (AuthException exception) {
Fluttertoast.showToast(
msg: 'too many request',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
return "error";
},
codeSent: (String verificationId, [int forceResendingToken]) async {
final _codeController = TextEditingController();
await showDialog(
context: context,
barrierDismissible: false,
builder: (context) => AlertDialog(
title: Text("write auth 6digit"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _codeController,
keyboardType: TextInputType.number,
),
],
),
actions: <Widget>[
FlatButton(
child: Text("verify"),
textColor: Constants.kPrimaryOrange,
// color: Constants.kPrimaryOrange,
onPressed: () async {
var _credential = PhoneAuthProvider.getCredential(
verificationId: verificationId,
smsCode: _codeController.text.trim());
โ
Error Occurs HERE โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
โ
await fAuth
.signInWithCredential(_credential)
.then((AuthResult result) async {
var snapshot = await Firestore.instance
.collection('users')
.where('pid', isEqualTo: result.user.phoneNumber)
.getDocuments();
/// id doesn't exist.
if (snapshot.documents.length == 0) {
await Firestore.instance
.collection('users')
.document(result.user.uid)
.setData({
'uid': result.user.uid,
'pid': result.user.phoneNumber,
'name': randomName,
'createdAt': DateTime.now(),
'storeName': '',
});
Fluttertoast.showToast(
msg: "33",
backgroundColor: Colors.black26,
textColor: Colors.white,
);
} else {
Fluttertoast.showToast(
msg: " id exists",
backgroundColor: Colors.black26,
textColor: Colors.white,
);
}
setUser(result.user);
Navigator.pushNamedAndRemoveUntil(
context, SplashScreen.id, (route) => false,
arguments: result.user);
โ
catch }).catchError((e) {
Fluttertoast.showToast(
msg: e.toString(),
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ErrorReading(errorMsg: e.toString())),
);
// Navigator.pop(context);
return "error";
});
},
),
FlatButton(
child: Text("close"),
textColor: Constants.kPrimaryOrange,
// color: Constants.kPrimaryOrange,
onPressed: () {
print('Error Occurs โญ');
Navigator.pop(context);
},
)
],
),
);
},
codeAutoRetrievalTimeout: (String verificationId) {
verificationId = verificationId;
});
I don't know cause of this problem , so i cannot fix it.
I used to toast to find error point.
then i found it โ
look at this emoji
anybody?
firebase_auth: ^0.16.1
firebase_core: ^0.4.0
cloud_firestore: ^0.13.0
firebase_storage: ^3.1.6
I tryed firebase_auth ^18 with core ^5 but many place to change recent code so I trying to figuring out with these versions
Follow the steps as mentioned here.
You need to add both the SHA-1 Fingerprint and enable the Device Check API for Phone Auth to work in Android.
If you need a code sample for Phone Auth to work in
firebase_auth ^18 with core ^5, do let me know will edit this answer.
Related
I started getting below error with Firebase Phone Authentication in my flutter app. What does error code 17499 mean? I couldn't get any info on this. Any hints to fix this? Thanks
E/FirebaseAuth(20851): [SmsRetrieverHelper] SMS verification code request failed: unknown status code: 17499 Requests from this Android client application xx.xxxxx.xxxxxxx are blocked.
E/flutter (20851): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
E/flutter (20851): #0 MethodChannelFirebaseAuth.verifyPhoneNumber.<anonymous closure>
#action
Future<void> getCodeWithPhoneNumber(
BuildContext context, String phoneNumber) async {
isLoginLoading = true;
await _auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: const Duration(seconds: 60),
verificationCompleted: (AuthCredential auth) async {
await _auth.signInWithCredential(auth).then((UserCredential value) {
if (value != null && value.user != null) {
print('Authentication successful');
onAuthenticationSuccessful(context, value);
} else {
loginScaffoldKey.currentState!.showSnackBar(SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
content: Text(
'Invalid code/invalid authentication',
style: TextStyle(color: Colors.white),
),
));
}
}).catchError((error) {
print(error.toString());
loginScaffoldKey.currentState!.showSnackBar(SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
content: Text(
'Something has gone wrong, please try later',
style: TextStyle(color: Colors.white),
),
));
});
},
verificationFailed: (FirebaseAuthException authException) {
if(authException != null && authException.message != null){
print('Error message: ' + authException.message!);
loginScaffoldKey.currentState!.showSnackBar(SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
content: Text(
authException.message!,
style: TextStyle(color: Colors.white),
), //Please enter your number in E.164 format.
));
isLoginLoading = false;
//Text(authException.message+' The phone number format is incorrect. [+][country code][number]'
}
},
codeSent: (String verificationId, [int? forceResendingToken]) async {
actualCode = verificationId;
isLoginLoading = false;
await Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => const OtpPage()));
},
codeAutoRetrievalTimeout: (String verificationId) {
actualCode = verificationId;
});
}
This worked from after migrating to Dart only FlutterFire initialisation method.
It stopped working with manual initialisation using google-services.json.
I'm using a Google Auth Sign in after the user signs in a Method initalize(); runs and states wether the user is a new user or existed user. but its always detecting a user as new user and resetting the data to default.
Google Login :
Future googleLogin() async {
try {
final googleUser = await googleSignIn.signIn();
if (googleUser == null) return;
_user = googleUser;
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
await FirebaseAuth.instance.signInWithCredential(credential);
initalize(); //<--------------The problem
} catch (e) {
print(e.toString());
}
notifyListeners();
}
Initialize() method:
initalize() async {
var user = FirebaseAuth.instance.currentUser!;
final snapShot = await FirebaseFirestore.instance
.collection('expenses')
.doc(user.uid)
.get();
if (!snapShot.exists) {
print(snapShot);
await SetTransaction(
uid: user.uid,
t_name: 't_name',
t_amt: '0',
isIncome: true,
Category: 'Any');
}
else{print('Yesss siirrr');}
}
Extra code
The google login happens here:
return Scaffold(
resizeToAvoidBottomInset:false,
backgroundColor: const Color(0xffedf1f4),
body: StreamBuilder(
stream:FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot){
if(snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData){
return LoggedInWidget();
}
else if (snapshot.hasError) {
return Center(child: Text('Something Went Wrong!'));
}else {
return SignUpWidget();
}
},
),
);
Button inside SignUpWidget(); class which helps to login:
GestureDetector(
onTap: () { //<------this happens on click of the button
print("Clicked");
final provider = Provider.of<GoogleSignInProvider>(
context,
listen: false);
provider.googleLogin();
},
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FaIcon(FontAwesomeIcons.google),
Text("Sign Up with Google")
],
),
padding: EdgeInsets.only(
left: 20, right: 20, top: 15, bottom: 15),
margin: EdgeInsets.symmetric(horizontal: 70.0),
decoration: BoxDecoration(
color: Color(0xffedf1f4),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.shade600,
offset: Offset(5, 5),
blurRadius: 5,
spreadRadius: 1),
BoxShadow(
color: Colors.white,
offset: Offset(-5, -5),
blurRadius: 5,
spreadRadius: 1,
)
],
),
),
),
googleLogin is a future method, it needs to await
GestureDetector(
onTap: () async{
...
await provider.googleLogin();
},
More about sync-await.
Here is my code section in which i am signing in user using firebase, now i wanted to show a loadihng screen while we are fetching data from firebase.
Container(
width: 376,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: <Color>[
Colors.black12,
Colors.blue,
Colors.black12,
]
)
),
child: TextButton(
onPressed: () async{
if(key.currentState!.validate()){
await FirebaseAuth.instance.signInWithEmailAndPassword(email: User_email_id.text, password: user_Passowrd.text)
.then((value) => {
Navigator.push(
context,
MaterialPageRoute(builder: (context)=>Page_First())
)
}).catchError((e){
Fluttertoast.showToast(msg: e!.message);
});
}
},
child: Text(
'Sign-in',
style: TextStyle(
fontSize: 17,
color: Colors.white,
),
),
),
),
Firstly, add boolean isLoading = false to the top of you class. Then move firebase loading code to a separate Future like this:
Future<void> loadFirebase(BuildContext context) async {
await FirebaseAuth.instance.signInWithEmailAndPassword(email: User_email_id.text, password: user_Passowrd.text)
.then((value) => {
Navigator.push(
context,
MaterialPageRoute(builder: (context)=>Page_First())
)
}).catchError((e){
Fluttertoast.showToast(msg: e!.message);
});
}
This function shall be called when the button is pressed. At the same time, isLoading shall be set to true. Finally, when building your widget, add a condition to show loading screen if isLoading is true.
isLoading == true ? LoadingContainer() : Container(content with button);
Hy Guys I have connected flutter to my firebase project and used AUTH feature in Firebase but what I would do is to show an error message when a wrong password or Email user is wrong.
this is my code:
Widget submitButton (){
return Container(
child: SizedBox(
width: 220,
height: 40,
child: MaterialButton(
elevation: 5,
onPressed: () async {
setState(() {
showProgress = true;
});
try {
final newUser = await _auth.signInWithEmailAndPassword(email: email, password: password);
print(newUser.toString());
if (newUser != null) {
Navigator.push(context, PageTransition(
type: PageTransitionType.fade,
child: WelcomeScreen(),
));
setState(() {
showProgress = false;
});
}
} catch (e) {}
},
child: Text('Accedi',style: TextStyle(color: Colors.black),),
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Colors.black12,width: 1)),
),
),
);
}
First you need to catch the error, you can do that by using catchError():
final newUser = await _auth.signInWithEmailAndPassword(email: email, password: password)
.catchError((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();
},
)
],
);
});
});
Then the showDialog will have err.message which will contain the error received from Firebase Authentication.
You have two options:
1.Use an alert dialog
void _showAlertDialog(String message) async {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(message),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
full example
Use errorText property in InputDecoration
TextField(
decoration: InputDecoration(
errorText: this.errorText,
),
)
full example
You can use a Form() with TextFormField()
Something like this:
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
key: ValueKey('email'),
validator: (value) {
if (value.isEmpty || !value.contains('#'))
return 'Please enter a valid Email address';
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(labelText: 'Email address'),
onSaved: (value) {
_userEmail = value;
},
),
It's just a dummy, but as you see there's some validation code in the validator attribute.
So what validator does is, if you return null everything is well and good, but if something is wrong, just return the String and it'll be shown below the text form field as an error message.
And to validate you can call a method like this to activate the method while form submission
void _trySubmit() {
final bool isValid = _formKey.currentState.validate();
FocusScope.of(context).unfocus();
if (isValid) {
_formKey.currentState.save();
widget.submitFn(
_userEmail.trim(),
_userName.trim(),
_userPassword.trim(),
_isLogin,
context,
);
}}
The method for getting isValid will invoke validation function of all TextFormFields, if all of them are okay, it'll return true else it'll return false.
All the _name are used to store the values in state variables using the onSaved attribute.
Let me know if you have anymore doubts.
Hope this helpsโ
I want to allow users to register an account on my app using flutter with email/password, and then send code to the phone. So when user enters their data to Sign up, it should register them with their email and then use their phone to the verity code. Also the user can't complete the registration and go to the Home page Without checking the entered code.
But in my code it's not working what i want do it.
My click function:
dynamic ruselt= await _auth.regsiterwithemail(_emailcontroller.text,_passwordcontroller.text);
if (ruselt!=null){
setState(() async {
loading =false;
verfitycode().verfityphoen(context);
});
}else{
setState(() {
loading=false;
SweetAlert.show(context,
title: "Title",
style: SweetAlertStyle.confirm,
subtitle: "Subtitle");
});
}
My registration function:
Future regsiterwithemail(String email , String password )
async {
try{
AuthResult result =await _auth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user =result.user;
print('oky');
return _userfirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
class for verity code
class verfitycode {
String phonenumber;
String smsCode;
String vialdid;
GlobalKey<FormState>_form;
Future<void> verfityphoen(BuildContext context)async{
final PhoneCodeAutoRetrievalTimeout AutoRetriv =(String verid) {
this.vialdid =verid;
};
final PhoneCodeSent smsCodeset =(String verid,[int forceResendingToken]){
this.vialdid=verid;
smscodeDialog(context);
};
final PhoneVerificationCompleted verfiedcompletd=(AuthCredential user){
print('verfild');
};
final PhoneVerificationFailed verfilederror =(AuthException exception){
print('${exception.message}');
};
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber:"+967776523152",
timeout: const Duration(seconds:5),
verificationCompleted: verfiedcompletd,
verificationFailed: verfilederror,
codeSent: smsCodeset,
codeAutoRetrievalTimeout: AutoRetriv
);
}
Future<bool> smscodeDialog(BuildContext context){
Alert(
context: context,
title: "ุฑู
ุฒ ุงูุชุญูู",
content: Column(
children: <Widget>[
Form(
key: _form,
child: Directionality(
textDirection: TextDirection.rtl,
child:
TextField(
onChanged: (val){
this.smsCode=val;
},
decoration:InputDecoration (
icon: Icon(Icons.supervisor_account),
labelText: 'ุงุฏุฎู ุฑู
ุฒ ุงูุชุญูู',
),
),
)
)
],
),
buttons: [
DialogButton(
child: Text('ุฎุฑูุฌ', style: TextStyle(color: Colors.white, fontSize:18)), onPressed:()=>Navigator.pop(context)),
DialogButton(
onPressed: (){
// _form.currentState.validate();
FirebaseAuth.instance.currentUser().then((user) {
if (user != null) {
Navigator.pop(context);
Navigator.push(context,
MaterialPageRoute(builder: (context) => Home()));
} else {
Navigator.pop(context);
_testSignlink();
}
});
},
child: Text(
"ุงุฏุฎู ุงูุฑู
ุฒ",
style: TextStyle(color: Colors.white, fontSize:18),
),
),
]).show();
}
_testSignlink() async {
FirebaseUser user;
String _smsCodeController;
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: vialdid,
smsCode: smsCode,
);
await user.linkWithCredential(credential).then((user){
print(user.user.uid);
}).catchError((onError){
print(onError.toString());
});
_smsCodeController = '';
return 'signInWithPhoneNumber succeeded: $user';
}
}