My code is working but it authenticate only the test phone no, which is given in the Firebase authentication.
when I'm trying with other number is directly going to PhoneVerificationFailed() and this is the exception msg im getting from this method :-
Error Message
Phone number verification failed. code: firebaseAuth. Message: this app is not authorized to use Firebase Authentication. Please verify that the correct package name and SHA-1 are configured in the Firebase Console. [ App validation failed]
Please have a look,and share your thoughts,may be im doing some mistakes.
// Example code of how to verify phone number
void _verifyPhoneNumber() async {
setState(() {
_message = '';
});
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential phoneAuthCredential) {
_auth.signInWithCredential(phoneAuthCredential);
setState(() {
_message = 'Received phone auth credential: $phoneAuthCredential';
});
};
final PhoneVerificationFailed verificationFailed =
(AuthException authException) {
setState(() {
_message =
'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}';
});
};
final PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async {
widget._scaffold.showSnackBar(const SnackBar(
content: Text('Please check your phone for the verification code.'),
));
_verificationId = verificationId;
};
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
_verificationId = verificationId;
};
await _auth.verifyPhoneNumber(
phoneNumber: _phoneNumberController.text,
timeout: const Duration(seconds: 5),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
}
// Example code of how to sign in with phone.
void _signInWithPhoneNumber() async {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: _verificationId,
smsCode: _smsController.text,
);
final FirebaseUser user =
(await _auth.signInWithCredential(credential)).user;
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
setState(() {
if (user != null) {
_message = 'Successfully signed in, uid: ' + user.uid;
} else {
_message = 'Sign in failed';
}
});
}
If u guys need full code please comment it,i'll share full code then
SHA-1 configuration is not completed at Firebase end,once SHA-1 Configuration is done it will start to run perfectly.
check this link for configuring SHA-1
https://stackoverflow.com/a/56091158/12072674
Related
This is the function I am using for to generate OTP and submitting OTP.
The OTP came once, but after that the OTP is not coming.
I even tried 2 different country code and numbers.
class AuthService with ChangeNotifier {
final FirebaseAuth _auth = FirebaseAuth.instance;
//Sign In
String userphone = "";
String verificationId;
String errorMessage = "";
Future verifyPhone(String phonenumber) async {
final PhoneVerificationFailed verificationFailed =
(FirebaseAuthException authException) {
print("Auth Exception is ${authException.message}");
};
final PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async {
print("verification id is $verificationId");
this.verificationId = verificationId;
};
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
this.verificationId = verificationId;
};
await _auth.verifyPhoneNumber(
phoneNumber: "+7" + phonenumber,
verificationCompleted: null,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout,
timeout: const Duration(seconds: 60),
);
}
Future signIn({#required String smsCode, context}) async {
AuthCredential authCredential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
UserCredential result = await _auth.signInWithCredential(authCredential);
User user = result.user;
await checkUser(result);
return _userFromFirebase(user);
}
}
}
The custom Button I am using to trigger the generate otp.
I tried on emulator as well as on my Real Device.
CustomButton(
buttonName: "Generate OTP",
function: () async {
if (_formKeySignIn.currentState.validate() &&
phonenumber.length == 10) {
Provider.of<AuthService>(context, listen: false).userphone =
phonenumber;
Provider.of<AuthService>(context, listen: false)
.verifyPhone(phonenumber);
widget.changeView();
} else {
setState(() {
error = "Please enter a valid phone number";
});
}
},
),
The code is correct! The mistake I was doing was, I also have to add the SHA Codes from the App Signing Section from the Play Publisher to the Firebase along with your apps SHA code. Then download the Google services json file again and replace your apps json file and generate the app bundle again.
I am using Firebase_auth package for verifying phone number, Firebase send code but when I check the validity of code it just show error. when I print code sent it is different with the code that I receive. any one know please help me.
thanks in advance.
here is my code:
await FirebaseAuth.instance.verifyPhoneNumber(
timeout: Duration(seconds: 60),
phoneNumber: phoneNumber,
verificationCompleted:
(PhoneAuthCredential phoneAuthCredential) {
print(phoneAuthCredential.smsCode);
print("complete");
},
verificationFailed: (e) {
print("failed");
print(e);
},
codeSent: (same, a) {
print(a);
print(same);
Navigator.of(context).pushNamed(
VerifyScreen.routName,
arguments: {
'code': a,
'customerId': customerId,
},
);
},
codeAutoRetrievalTimeout: (sa) {
print(sa);
print("timeout");
},
);
I know the code received cannot be printed, but it comes in encrypted form verificationId.
When the entered code is verified, you send the code that was entered by the user and the verificationId to Firebase to verify it.
If your goal is to be verified automatically without entering the code through this verificationCompleted, you can transfer the user automatically.
Note: Provided that the sim card is on the same phone to which the code was sent.
Additional information: If you want the process to be automatic, use the following code:
Future singInPhoneNumber() async {
FirebaseAuth _auth = FirebaseAuth.instance;
_auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: 60),
verificationCompleted: (AuthCredential phoneAuthCredential) async {
//Automatically verify
Navigator.of(context).pushNamed(
VerifyScreen.routName,
arguments: {
'code': a,
'customerId': customerId,
},
);
debugPrint("Firebase Auth :Auto Verification Completed");
},
verificationFailed: (FirebaseAuthException error) {
debugPrint("ERROR Firebase Auth : AuthException : ${error.message}");
showToast(context, 'Something went wrong, please try again later');
},
codeSent: (String verificationId, [int forceResendingToken]) {
setState(() {
this.verificationId = verificationId;
});
},
codeAutoRetrievalTimeout: (String verificationId) {
return null;
},
);
}
If you only want to enter the code manually:
AuthCredential credential = PhoneAuthProvider.credential(
verificationId: verificationId, smsCode: codeController.text);
_auth
.signInWithCredential(credential)
.then((value) => {
print('The operation completed successfully')
})
.catchError((onError) {
print(onError.toString());
});
I have implemented the Firebase phone authentication on my flutter application. But anytime I send invoke the initAuth method, I get code sent on my console then after 60 secs timed out. That I understand is simply coming from my code but I expected an SMS or an auto login. It seems I don't ever get the verificationCompleted method invoked.
Below is my code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class PhoneVerification{
initAuth({BuildContext context, String phoneNumber}) async{
print(phoneNumber);
var firebaseAuth = FirebaseAuth.instance;
await firebaseAuth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: 60),
codeSent:(String verificationId, [int forceResendingToken]){
print("Code Sent");
},
codeAutoRetrievalTimeout: (String verificationId){
print("Timed out");
},
verificationCompleted: (AuthCredential auth) async {
print("This User is authenticated by google play services");
firebaseAuth.signInWithCredential(auth)
.then((AuthResult result) =>{
if(result != null && result.user != null){
print("Authentication is Successful")
}else{
print("Authentication failed!")
}
})
.catchError((error){
print(error);
});
},
verificationFailed: (AuthException authException){
print('Error message: ' + authException.message);
},
);
}
}
This is the method I wrote to invoke the initAuth method:
Future<void> sendSMS({context}) async{
User user = Provider.of<UserProvider>(context, listen: false).user;
PhoneVerification phoneVerification = PhoneVerification();
await phoneVerification.initAuth(context: context, phoneNumber: user.phone);
}
Then finally, I am making the actual call onPress of a button in a component. Below is how I invoked the sendSMS method.
EnterPhone(onPress: ()=> sendSMS(context: context)),
for me :
// For firebase auth
final auth = FirebaseAuth.instance;
//
final PhoneVerificationCompleted verificationCompleted =
(AuthCredential phoneAuthCredential) async {
final res = await auth.signInWithCredential(phoneAuthCredential);
// Todo After Verification Complete
);
};
//
final PhoneVerificationFailed verificationFailed =
(AuthException authException) {
print('Auth Exception is ${authException.message}');
};
//
final PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async {
print('verification id is $verificationId');
verId = verificationId;
};
//
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) {
verId = verificationId;
};
//
await auth.verifyPhoneNumber(
// mobile no. with country code
phoneNumber: '+91${_mobile.text}',
timeout: const Duration(seconds: 30),
verificationCompleted: verificationCompleted,
verificationFailed: verificationFailed,
codeSent: codeSent,
codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
I am developing a flutter application in which I am trying to authenticate the user with Firebase Phone Authentication.
According to Firebase policy, we can't get Authentication code while debugging so I have to add my phone number to the firebase console with a predefined code.
Now It's working fine while debugging but when I use it in release mode when Google Play Services verified the phone, my application crashes. But when I open the app again it's authenticated and works fine. How do I debug this crash?
Here's my code
signInWithPhone(String phone) {
_authStatus = AuthStatus.Authenticating;
notifyListeners();
try {
_auth.verifyPhoneNumber(
phoneNumber: phone,
timeout: Duration(seconds: 60),
verificationCompleted: (AuthCredential _authCredential) {
_getFirebaseUser(_authCredential);
print("verificationCompleted: ${_authCredential.providerId}");
},
verificationFailed: (AuthException authException) {
print("Auth Failed: ${authException.message}");
_authStatus = AuthStatus.Uninitialized;
notifyListeners();
},
codeSent: (String verificationId, [int forceResendingToken]) {
this.verificationId = verificationId;
print("Code Sent: $verificationId");
_authStatus = AuthStatus.CodeSent;
notifyListeners();
},
codeAutoRetrievalTimeout: (String verificationId) {
this.verificationId = verificationId;
print("Actual Code: $verificationId");
});
} catch (e) {
print(e.toString());
}
}
void _getFirebaseUser(AuthCredential authCredential) async {
try {
AuthResult authResult =
await _auth.signInWithCredential(authCredential).catchError((e) {
print(e.toString());
});
_firebaseUser = authResult.user;
notifyListeners();
} catch (e) {
print(e.toString());
_authStatus = AuthStatus.Uninitialized;
notifyListeners();
}
}
I am facing an issue with Firebase phone authentication, where, when I use _auth.signInWithCredential(), it doesnt come out of the function and is stuck there...
Here is my code:
Future<void> verifyPhoneNumber(String phoneNumber) async {
await _auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: Duration(seconds: 60),
verificationCompleted: (AuthCredential credential) async {
print('Verification OTP completed');
AuthResult result = await _auth.signInWithCredential(credential);
FirebaseUser user = result.user;
if (user != null) {
print('User is not null!');
Navigator.pushReplacementNamed(context, 'home');
}
},
verificationFailed: (AuthException exception) async {
print('There was a problem sending the otp');
print(exception.code);
print(exception.message);
},
codeSent: (String verificationID, [int forceResendingToken]) {
createAlertDialog(context, widget.isFromGoogleAuth, verificationID);
},
codeAutoRetrievalTimeout: null);
}
Next, when the user presses a button I run this:
onTap: (pin) async {
otpText = pin.trim();
print('$otpText');
AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationID, smsCode: otpText);
print('${verificationID}');
print('${credential.providerId}');
//everything until now has been printed, nothing is null
AuthResult authResult = await _auth
.signInWithCredential(credential)
.then((value) {
//this value is not printed
print('${value.user.phoneNumber}');
});
//The next line of code doesnt get run, and it doesnt print value.user.phone number
print('I HAVE REACHED HERE');
FirebaseUser user = authResult.user;
if (user != null) {
Navigator.pushReplacementNamed(context, 'home');
} else {}
},
The problem was that, in the test users, I had added my phone number, and instead of using the OTP code which I assigned to it there, I used some old OTP codes sent to my phone, which caused signInWithCredential to throw errors. Thanks for the help and I appreciate it
Try this
onTap: (pin) async {
otpText = pin.trim();
print('$otpText');
AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationID, smsCode: otpText);
print('${verificationID}');
print('${credential.providerId}');
//Made changes here
AuthResult authResult = await FirebaseAuth.instance
.signInWithCredential(credential)
.then((value) {
print('${value.user.phoneNumber}');
});
print('I HAVE REACHED HERE');
FirebaseUser user = authResult.user;
if (user != null) {
Navigator.pushReplacementNamed(context, 'home');
} else {}
},