I am using below code for firebase authentication.
void NavigateToOtp(){
//Navigate to another screen
}
Future<void> verifyPhone() async {
final PhoneCodeSent smsOTPSent = (String verId, [int forceCodeResend]) {
this.verificationId = verId;
};
try {
await _auth.verifyPhoneNumber(
phoneNumber: '+XX XXXXXXXXXX', // PHONE NUMBER TO SEND OTP
codeAutoRetrievalTimeout: (String verId) {
//Starts the phone number verification process for the given phone number.
//Either sends an SMS with a 6 digit code to the phone number specified, or sign's the user in and [verificationCompleted] is called.
this.verificationId = verId;
},
codeSent:
smsOTPSent, // WHEN CODE SENT THEN WE OPEN DIALOG TO ENTER OTP.
timeout: const Duration(seconds: 20),
verificationCompleted: (AuthCredential phoneAuthCredential) {
print(_auth.currentUser());
print(phoneAuthCredential);
NavigateToOtp();
},
verificationFailed: (AuthException exceptio) {
print('${exceptio.message}');
});
} catch (e) {
handleError(e);
}
}
void sendOtp(){
verifyPhone();
}
But is showing me below error :
[FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq#847da6d
I am using Android emulator Pixel API 29.
Added phone number in Google-sign and enable phone signin providers in firebase console
Also created SHA key and also added google firebase plugin in .gradle file
I am using this code : https://www.c-sharpcorner.com/article/otp-authentication-in-flutter-using-firebase/
In the new Firebase auth version, they've made major changes like Recaptcha for human verification.it needs a browser to verify so, Add below dependency to your build.gradle file
implementation 'androidx.browser:browser:1.3.0'
This will help firebase to open the browser for a reCAPTCHA verification.
Related
I'm using firebase auth for phone number verification in my flutter project, it works fine as it sends the OTP code to the device but verificationcompleted method which autoverifies the phone number does not call at all. I have followed all the configuration setups, Device verification api is enabled in Google cloud console. Now i am not sure if the firebase removed this autoverified or not because i did not find anything about it in their documentaion,
Here is the code to get OTP Code.
Future getPinCode() async {
print("Starting OTP process");
_auth.verifyPhoneNumber(
phoneNumber:
"+92${phoneNumber.toString()}",
timeout: const Duration(seconds: 60),
verificationCompleted: _verificationCompleted,
verificationFailed: _verificationFailed,
codeSent: _codeSent,
codeAutoRetrievalTimeout: _codeAutoRetrievalTimeout,
);
}
_verificationCompleted(PhoneAuthCredential authCredential) {
log("verificationCompleted ");
_auth.signInWithCredential(authCredential).then((UserCredential result) {
Get.to(() => const HomePage());
}).catchError((e) {
log(e);
});
}
here in verificationcompleted Im signing user and navigating to homePage, but this method never gets called
_verificationFailed(FirebaseAuthException authException) {
print(authException.message);
}
_codeSent(String verificationId, int? resendToken) async {
log("codeSent $verificationId");
verificationCode =
verificationId; // Update the UI - wait for the user to enter the SMS code
//String smsCode = 'xxxx';
// Create a PhoneAuthCredential with the code
//PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);
// Sign the user in (or link) with the credential
//await _auth.signInWithCredential(credential);
}
_codeAutoRetrievalTimeout(String verificationId) {
verificationCode = verificationId;
log("Timout");
}
output Log (1)
output Log (2)
I authenticate through firebase phone auth, and on Android, I want to authenticate automatically through "verificationComplete".
However, the function "codeSent" is called instead of "verificationCompleted".
Future<void> _sendingCode(String phoneNum, BuildContext context) async {
FirebaseAuth auth = FirebaseAuth.instance;
return await auth.verifyPhoneNumber(
phoneNumber: phoneNum,
forceResendingToken: _forceResendingToken,
verificationCompleted: (PhoneAuthCredential credential) async {
logger.d('verificationCompleted - $credential');
// Sign the user in (or link) with the auto-generated credential
await auth.signInWithCredential(credential).then((value) async {
// next page
context.read<PageController>().animateToPage(2,
duration: Duration(milliseconds: 500), curve: Curves.ease);
}).catchError((e) => logger.w(e));
},
codeAutoRetrievalTimeout: (String verificationId) {
logger.w('timeout');
},
codeSent: (String verificationId, int? forceResendingToken) {
logger.d("$phoneNum send code");
_verificationId = verificationId;
_forceResendingToken = forceResendingToken;
},
verificationFailed: (FirebaseAuthException error) {
logger.e("Error: $error");
},
);
}
Can I know the cause of this problem?
onVerificationCompleted() will only be called when the phone number has been verified without any input from the user. To do what you are trying, you should be sending your action inside onCodeSent() instead.
Obtain phone number from user
Call PhoneAuthProvider.verifyPhoneNumber(auth) (as you are already) to send the pin to the user
onCodeSent() is called, with the verification ID and a resending token.
Inside of onCodeSent(), create an method to launch the "pin input screen" with the verification ID.
Get a pin from the user and then combine it with the verification ID by calling PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, userInput)
Use that credential to sign in the user using signInWithCredential(credential).
You have to implement both functions. onVerificationCompleted function not working all the time.
More details about onVerificationCompleted link
Add the same logic inside your codeSent method.
I've firebase auth services in my flutter app. It's working on emulator & real device (while debug). But when i publish it on google play neither alpha test or release version it doesn't work.
Main.dart
StreamProvider(
create: (context) => context.read<AuthenticationService>().authStateChanges,
)
AuthService
final FirebaseAuth _firebaseAuth;
AuthenticationService(this._firebaseAuth);
AccessToken accessToken;
Stream<User> get authStateChanges => _firebaseAuth.idTokenChanges();
SignedIn Method in AuthService
Future<String> signIn({String email, String password}) async {
try {
await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
String uid = await FirebaseAuth.instance.currentUser.uid;
return "Signed in";
} on FirebaseAuthException catch (e) {
return e.message;
}
}
Login.dart
var login = await context.read<AuthenticationService>().signIn(email: mailController.text, password: sifreController.text);
It could be that you forgot to put the Google Play fingerprint into your Firebase App configuration.
If the Google Play fingerprint are not present on your app, there is no way for the user to connect to Firebase services.
You can find your Google play fingerprint into the Setup -> App Signing menu.
See the picture below
You should then add them in the android settings of your firebase app.
I have a react native application which uses google sign in. currently, I can sign in with one of my google accounts which my mobile signed in, but I need to do an OAuth for another google account in my google accounts stack, this is to get the API access I need the serverAuthToken for the secondary accounts
The library I'm using for google login - https://github.com/react-native-community/google-signin
What I have done till now:
const firebaseGoogleLogin = async () => {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
if (userInfo) {
await storeToken(userInfo);
// eslint-disable-next-line no-console
console.log('User info retrieved during login', userInfo);
}
// create a new firebase credential with the token
// eslint-disable-next-line max-len
const credential = firebase.auth.GoogleAuthProvider.credential(userInfo.idToken, userInfo.accessToken);
// login with credential
// eslint-disable-next-line no-unused-vars
const firebaseUserCredential = await firebase.auth().signInWithCredential(credential);
console.log('Logged in')
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log('sign in cancelled', error);
} else if (error.code === statusCodes.IN_PROGRESS) {
console.log('signin in progress error', error);
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log('play services are not available or outdated', error);
} else {
console.log('some other error occurred', error);
}
}
};
Result for the above code:
This is the code I used to login with my primary Google account, after logging in I'm triggering the play services modal to sign in with other accounts using the above, but the modal closes with loading a sec and gets closed, shows me Logged in in the log, since I have already logged, in the play services automatically bypass the option to select an account
The above problem occurs only in android, ios seems fine even after logging in with an account
Was trying to do a hack if there isn't a way for multiple account authorization since an account already signed in it is bypassing the play service modal, I'm thinking to logout the user once he signed into my application (process level) and inside the main activity, I can have the play services still? is this the right way to do!
Probably you have fixed the issue. I think the method below will solve your problem. Call this after logout.
signOut = async () => {
try {
await GoogleSignin.revokeAccess();
await GoogleSignin.signOut();
this.setState({ user: null }); // Remember to remove the user from your app's state as well
} catch (error) {
console.error(error);
}
};
First import { GoogleSignin } from "#react-native-google-signin/google-signin"; in your logout file
If you're using firbase authentication after
auth().signOut().then(() => {
GoogleSignin.revokeAccess();
});
I am using https://github.com/arnesson/cordova-plugin-firebase to implement firebase phone authentication.
When i call verifyPhoneNumber()...It console me verificationId.
Code sample :
this.firebase.verifyPhoneNumber(phoneNumber,60)
.then(
function (verificationId) {
console.log(verificationId)
return verificationId;
}
)
Console Output:
Object {
instantVerification: false,
verificationId: "here verification id"
}
But, it is not sending code to given phone number.
Any help ?
As i can read in the documentation, they said you need to sign in with you'r credential before send SMS. Maybe you do it before u'r sample code, if you don't you use this instead of you'r code :
window.FirebasePlugin.verifyPhoneNumber(number, timeOutDuration, function(credential) {
console.log(credential);
// ask user to input verificationCode:
var code = inputField.value.toString();
var verificationId = credential.verificationId;
var credential = firebase.auth.PhoneAuthProvider.credential(verificationId, code);
// sign in with the credential
firebase.auth().signInWithCredential(credential);
// call if credential.instantVerification was true (android only)
firebase.auth().signInWithCustomToken(customTokenFromYourServer);
// OR link to an account
firebase.auth().currentUser.linkWithCredential(credential)
}, function(error) {
console.error(error);
});