User Firebase Phone Auth - android

Is it possible to use Phone Auth just to verify a phone number? My users are already logged in with other providers. I only need to make sure that the number they have entered is valid.

You can do this using Firebase's PhoneAuthProvider which will send sms of one time code to the user phone number through which the user is verified.
The implementation is given in this documentation: Firebase phone authentication

lets say that You can't verify the phone number without creating a new user linked to this number in firebase using the manual verification
but you can unlink the phone from the user account soon after, by calling:
FirebaseAuth.getInstance().getCurrentUser().
unlink(PhoneAuthProvider.PROVIDER_ID)
.addOnCompleteListener(this);
just like:
final PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, scode);
mAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseAuth.getInstance().getCurrentUser().
unlink(PhoneAuthProvider.PROVIDER_ID)
.addOnCompleteListener(this);
register_user(sname,semail,sphone,scode, spass); // this if you wanna register with a different method
}
}
});
And There is the possibility of auto verification of Google Play Services (in the new phones). When onVerificationCompleted(PhoneAuthCredential) in your PhoneAuthProvider.OnVerificationStateChangedCallbacks is called. and here the verification is completed with no need from the user to type anything and the phone will not linked to a new user account.
PhoneAuthProvider.getInstance().verifyPhoneNumber(sphone, 60, TimeUnit.SECONDS, AuthActivity.this, new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
register_user(sname,semail,sphone,scode, spass); // this if you wanna register with a different method
}
#Override
public void onVerificationFailed(FirebaseException e) {
}
#Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken token) {
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
mResendToken = token;
// ...
}
});
I think that google should allow to the developers to verify the phone without creating user account that will be so helpful

Related

Firebase SMS authentication sign-in methods

I have this Android code for Firebase sign in using SMS code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseApp.initializeApp(this);
userLoggedIn();
mPhoneNumber = findViewById(R.id.phoneNumber);
mCode = findViewById(R.id.code);
mSend = findViewById(R.id.send);
mAuth = FirebaseAuth.getInstance();
mSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mVerificationId != null) {
// verifyPhoneNumberWithCode(mVerificationId, mCode.getText().toString());
verifyPhoneNumberWithCode(mVerificationId, mCode.getText().toString());
} else {
startPhoneNumberVerification();
}
}
});
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
Log.d(TAG, "onVerificationCompleted:" + phoneAuthCredential);
signInWithPhoneAuthCredentials(phoneAuthCredential);
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
}
#Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(verificationId, forceResendingToken);
mVerificationId = verificationId;
mSend.setText("Verify Code");
}
};
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredentials(credential);;
}
private void startPhoneNumberVerification() {
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber(mPhoneNumber.getText().toString()) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
private void signInWithPhoneAuthCredentials(PhoneAuthCredential phoneAuthCredential) {
FirebaseAuth.getInstance().signInWithCredential(phoneAuthCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()) {
userIsLoggedIn();
}
}
});
}
private void userIsLoggedIn() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
startActivity(new Intent(getApplicationContext(), MainPageActivity.class));
finish();
return;
}
}
The code works fine BUT after I added the following 2 sign-in methods on firebase project console, the app doesn't require new users to verify the SMS code any more - meaning, new users get signed in automatically after getting the code without punching in the code on the app.
Firebase Authentication Sign-in providers console
Google
Google sign-in is automatically configured on your connected iOS and
web apps. To set up Google sign-in for your Android apps, you need to
add the SHA1 fingerprint for each app on your Project Settings.
Email/password
Allow users to sign up using their email address and password. Our
SDKs also provide email address verification, password recovery, and
email address change primitives. Learn more
I have both SHA-1 and SHA-256 configures on my project.
Any ideas why it signs new users in automatically without verifying SMS code sent?
Instant verfication might be happening with your phone number.
I have observed that with our numbers most of times Auto-retrieval works.
I'm guessing this behavior might be happening based on service provider/country code/device or other factors.
https://firebase.google.com/docs/auth/android/phone-auth#onverificationcompletedphoneauthcredential
onVerificationCompleted(PhoneAuthCredential)
This method is called in two situations:
Instant verification: in some cases the phone number can be instantly
verified without needing to send or enter a verification code.
Auto-retrieval: on some devices, Google Play services can
automatically detect the incoming verification SMS and perform
verification without user action. (This capability might be
unavailable with some carriers.)
In either case, the user's phone number has been verified successfully, and you can use the PhoneAuthCredential object that's passed to the callback to sign in the user.

Firebase database listener not working after Firebase PhoneAuth Signout

I have made an Android application using Firebase Phone Authentication and Realtime Database.
My requirement is to first check if the user's no. is in my database or not and then send him the OTP.
My database:
My code:
rootRef= FirebaseDatabase.getInstance().getReference().child("Employees").child("mobno");
//---------------1----------------
getcodeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("abcd","get code button clicked");
if (!cugET.getText().toString().trim().isEmpty() && cugValidFlag==true) {
Log.d("abcd","entered no. is valid");
enteredcugno = cugET.getText().toString().trim();
Log.d("abcd","Entered cugno: "+enteredcugno);
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("abcd","rootRef listener reached");
if(dataSnapshot.child(enteredcugno).exists()){
Log.d("abcd","cugno exists in db");
startPhoneNumberVerification(cugET.getText().toString().trim());
mVerified = false;
otpTV.setVisibility(View.VISIBLE);
otpET.setVisibility(View.VISIBLE);
otpValTV.setVisibility(View.VISIBLE);
verifycodeBtn.setVisibility(View.VISIBLE);
}
else{
Log.d("abcd","cugno doesn't exists in db");
Toast.makeText(cugLogin.this,"No such CUG No. found",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
//------------------------2--------------------
private void startPhoneNumberVerification(String phoneNumber) {
Log.d("abcd","startPhoneNumberVerification");
// [START start_phone_auth]
PhoneAuthProvider.getInstance().verifyPhoneNumber(
"+91"+phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
// [END start_phone_auth]
}
//--------------3--------------------
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
// This callback will be invoked in two situations:
// 1 - Instant verification. In some cases the phone number can be instantly
// verified without needing to send or enter a verification code.
// 2 - Auto-retrieval. On some devices Google Play services can automatically
// detect the incoming verification SMS and perform verificaiton without
// user action.
Log.d("abcd", "onVerificationCompleted:" + credential);
signInWithPhoneAuthCredential(credential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
// This callback is invoked in an invalid request for verification is made,
// for instance if the the phone number format is not valid.
Log.w("abcd", "onVerificationFailed", e);
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Log.d("abcd","verification failed cz of FirebaseAuthInvalidCredentialsException");
Toast.makeText(cugLogin.this,"Verification Failed !! Invalied verification Code",Toast.LENGTH_SHORT).show();
}
else if (e instanceof FirebaseTooManyRequestsException) {
Log.d("abcd","verification failed cz FirebaseTooManyRequestsException");
Toast.makeText(cugLogin.this,"Verification Failed !! Too many request. Try after some time. ",Toast.LENGTH_SHORT);
}
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
// The SMS verification code has been sent to the provided phone number, we
// now need to ask the user to enter the code and then construct a credential
// by combining the code with a verification ID.
Log.d("abcd", "onCodeSent:" + verificationId);
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
mResendToken = token;
}
};
//----------------4---------------
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
Log.d("abcd","signInWithPhoneAuthCredential reached");
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d("abcd", "signInWithCredential:success");
FirebaseUser user = task.getResult().getUser();
mVerified = true;
timer.cancel();
timerTV.setVisibility(View.INVISIBLE);
cugET.setEnabled(false);
cugTV.setVisibility(View.INVISIBLE);
cugET.setVisibility(View.INVISIBLE);
getcodeBtn.setVisibility(View.INVISIBLE);
otpTV.setVisibility(View.INVISIBLE);
otpET.setVisibility(View.INVISIBLE);
otpValTV.setVisibility(View.INVISIBLE);
verifycodeBtn.setVisibility(View.INVISIBLE);
Intent intent = new Intent(cugLogin.this,Login.class);
intent.putExtra("cugnotoLogin",enteredcugno);
startActivity(intent);
Toast.makeText(cugLogin.this,"Successfully verified",Toast.LENGTH_SHORT).show();
// ...
} else {
// Sign in failed, display a message and update the UI
Log.w("abcd", "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
Toast.makeText(cugLogin.this,"Invalid OTP ! Please enter correct OTP",Toast.LENGTH_SHORT).show();
}
}
}
});
}
The last log I see is "Entered cugno: 9876543210"
No error being shown, I am really confused how can I correct it?
If I remove the rootRef listener my code is working but I want to check the user in the database first. Also I am giving the correct path to the rootRef then why isn't it working?
EDIT
I got my code working but I am still a bit confused, I just moved my rootRef initialization in the getcodeBtn listener. But I already had it in my onStart() function so it should have been initialized there as well, if anyone knows the reason behind it please let me know.
LATEST EDIT
Now when I signed out, my code is again stuck at the rootRef listener, it isn't getting passed into it. Even after closing the app it isn't letting me in. It's the same thing happening again. It's like something got refreshed overnight and the app let me sign in and when I signed out, I am stuck again. Why is this happening?
I solved it, it wasn't the coding problem but the logic was faulty. I set the rules of the database for the authenticated users only, and was checking my database first to let the user to sign in, so when I logged out, the code went into a loop as it couldn't access the database to let the user sign in.

Can I use Firebase "Phone Number Authentication" feature for the phone number verification purpose?

I am actually using Firebase Google auth for signing in the user and after that, I want to take the basic details of the user into the database which also includes the mobile number of a user, so my question is can use Phone Number Authentication just to verify the mobile number of user (using OTP) and after that I can store it into database?
Thank You!
If you are already signing in a user with Google. You can link/update the phone number for that user:
https://firebase.google.com/docs/reference/js/firebase.User#updatePhoneNumber
https://firebase.google.com/docs/reference/js/firebase.User#linkWithPhoneNumber
This means the user will have 2 providers linked (phone/google.com). The user will be able to sign in with either in the future. Though if you only want to expose Google as the provider. You can just provide that in your sign in page.
You can store the user in the database too.
Because Firebase Authentication is amazing,
you can have more than one authentication "method" on an account:
In this example, the app in question, allows users to create an account using either
phone
email
Facebook link
So. On the welcome screen of the app, it says "Join SuperApp, using phone, email or Facebook link!!" and there's three buttons for those three methods.
But in fact, the way Firebase Authentication works, each user can actually have more than one of those.
The third user there has both email and phone authentication. The fourth user there has all three!
So, let's say a user creates an account with "email authentication".
Later, there will be a button that says "Also link your Facebook account!",
and another one, "Also link your phone number!"
(Note that in many cases, depending on what your startup is, you may want users to have more than one authentication method, for greater security. Or, you may just want to make it easier for them to log in.)
Incredibly, Firebase can handle all that. (Or, you can spend a year developing it by hand!)
Some points...
Yes, Firebase entirely takes care of sending the email or SMS verification codes. Completely automatic.
Note that you can't "use" the amazing email/phone verification service "for other purposes". For example, in an app we're doing there's a feature where you need to verify a purchase or something, using an SMS code. Note that that has absolutely nothing to do with the user logging-in, it's just an unrelated feature in the app which uses an SMS code. You can not (unfortunately!) use Firebase's epic SMS-system to do that. (You'd just use any of the widely available sms-code-sending services, instead.)
A huge point of confusion. Note that the email and/or phone number discussed here are stored by Firebase in the Firebase Authentication system. The image above is from the Firebase Authentication system. There is NO CONNECTION AT ALL to your data tables. So, almost every app has in the data tables something like "userData/". Sure, you may, for your convenience (or whatever) have fields in the data tables like "email" "Facebook name" or whatever. Those fields have NO CONNECTION AT ALL, in any way, to the "actual, real" Firebase Authentication system (as seen in the image above). Those are just fields you populate in your development - they could hold any value you put in there. There are many, many questions here on SO where folks confuse some value "user_email" that happens to be in the database, with the "actual, real" email or phone used by Firebase in the Firebase Authentication system.
Note that if you start off with Facebook or another social authentication. Sometimes those social media have the users email/phone/etc. But that has absolutely no connection to the actual Firebase authenticated email/phone.
If the user happens to need to change their actual authenticated email or phone, there's a function for that link
The Firebase Authentication system is so amazing that many mobile projects use Firebase purely for the convenience of the amazing Firebase Authentication system, even if they are not especially using Firebase as such.
(One detail on the email front. You'll use your own email server to send the emails. (ie, godaddy or sendmail or whatever - just whatever email server you normally use.) There's a slot on the backend of Firebase where you just type in your email server/password. Alternately, during development/testing Firebase will even send the email for you, but it only arrives slowly since it's a mass-used account being used by about a zillion Firebase-app-developers like yourself.)
Summary
Amazingly you can have more than one authentication method, it is all handled by Firebase
Note that any phone/email etc you may happen to have in your data, has absolutely No connection to the "actual" phone/email in Firebase Authentication
In the Firebase console, look on the left and go one above "Database" to see "Authentication" ! Many news developers don't realize this!
If you want to use firebase phone authentication for phone number verification only, according to me you do this but by implementing following:
First in Sign-in Method page, enable the Phone Number sign-in method and to send verification code on phone number use this
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
you will get response in mCallbacks and to initialize callback use this
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
// this method executed if phone number verified you can do your stuff here if you only want to verify phone number.
// or you can also use this credentials for authenticate purpose.
}
#Override
public void onVerificationFailed(FirebaseException e) {
// This callback is invoked in an invalid request for verification is made,
// for instance if the the phone number format is not valid.
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
// The SMS verification code has been sent to the provided phone number, we
// now need to ask the user to enter the code and then construct a credential
//and then execute your method if number entered is correct.
}
};
Don't forgot to use latest firebase dependencies like
compile 'com.google.firebase:firebase-auth:11.4.2'
Hope this will help you.
private FirebaseAuth mAuth;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
String mVerificationId = "";
PhoneAuthProvider.ForceResendingToken mResendToken;
mAuth = FirebaseAuth.getInstance();
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks()
{
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
//edtVerify.setText(phoneAuthCredential.getSmsCode());
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Log.e("Invalid Phone Number ","====>");
} else if (e instanceof FirebaseTooManyRequestsException) {
Log.e("Quota exceeded ","====>");
}
}
#Override
public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken token) {
mVerificationId = verificationId;
mResendToken = token;
}
};
//SEND VERIFICATION CODE...
try {
PhoneAuthProvider.getInstance().verifyPhoneNumber(mLastEnteredPhone, 120,
TimeUnit.SECONDS,
mContext,
mCallbacks);
} catch (Exception e) {
e.printStackTrace();
}
//VERIFY CODE...
try {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredential(credential);
} catch (Exception e) {
e.printStackTrace();
}
//SIGN IN WITH PHONE...
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential)
{
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful())
{
FirebaseUser user = task.getResult().getUser();
String currentUid = user.getUid();
String currentPhone = user.getPhoneNumber();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Log.e("Invalid Code ","====>");
}
}
}
});
}
Yes you can use it with the help of following code
PhoneAuthProvider.getInstance().verifyPhoneNumber(
mobnum, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
verificationId=s;
}
#Override
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(getApplicationContext(),"Verification Failed"+e.getMessage(),Toast.LENGTH_LONG).show();
}
}); // OnVerificationStateChangedCallbacksPhoneAuthActivity.java
after that you have to use the following method
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Intent i = new Intent(Otp_Verification_Activity.this,HomeActivity.class);
startActivity(i);
finish();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
}
}
}
});
}
and for more you can visitclickhere
and you watch video on youtube clickhere

Firebase Phone Authentication credentials linking with Google login in firebase

I have implemented two step authentication in my app using firebase authentication in which I have used gmail, facebook or simple email login for authenticating. As digits phone verification has migrated to firebase i have implemented firebase phone authentication by linking the existing logged in account (facebook, gmail, or email) with phone authentication credentials. It works fine when used with facebook and email account. When user is logged in through google and tries to verify mobile through phone authentication this logs are printed :
signInWithCredential:failure
com.google.firebase.auth.FirebaseAuthUserCollisionException: An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.
Read this article. Is it the same issue as mentioned in the article?? Is there any solution for the same..
After research over internet and in firebase documentation itself I found solution to this two step authentication in app using firebase auth.
firebaseAuth.getCurrentUser().updatePhoneNumber(credential).addOnCompleteListener(this, new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInWithCredential:success");
Snackbar.make(findViewById(android.R.id.content), "Mobile Verified Successfully.",
Snackbar.LENGTH_SHORT).show();
} else {
Log.w(TAG, "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
//mVerificationField.setError("Invalid code.");
Snackbar.make(findViewById(android.R.id.content), "Invalid Code.",
Snackbar.LENGTH_SHORT).show();
} else {
Toast.makeText(context,"signInWithCredential:failure"+task.getException(),
Snackbar.LENGTH_LONG).show();
}
}
}
});
Just pass the PhoneAuthCredential to above method and it will verify the phone assigns to your existing account. Make sure it is not used by any other account.
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
now phone auth is available in firebase.Here is Code for Phone Auth using Firebase:
If there is any question fee free to ASK me.
EditText phoneNum,Code; //// two edit text one for enter phone number other for enter OTP code
Button sent_,Verify; // sent_ button to request for verification and verify is for to verify code
private PhoneAuthProvider.ForceResendingToken mResendToken;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
private FirebaseAuth mAuth;
private String mVerificationId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_number_auth);
phoneNum =(EditText) findViewById(R.id.fn_num);
Code =(EditText) findViewById(R.id.code);
sent_ =(Button)findViewById(R.id.sent_nu);
Verify =(Button)findViewById(R.id.verify);
callback_verificvation();
mAuth = FirebaseAuth.getInstance();
sent_.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String num=phoneNum.getText().toString();
startPhoneNumberVerification(num); // call function for receive OTP 6 digit code
}
});
Verify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String code=Code.getText().toString();
verifyPhoneNumberWithCode(mVerificationId,code); //call function for verify code
}
});
}
private void startPhoneNumberVerification(String phoneNumber) {
// [START start_phone_auth]
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
// [END start_phone_auth]
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
FirebaseUser user = task.getResult().getUser();
Toast.makeText(getApplicationContext(), "sign in successfull", Toast.LENGTH_SHORT).show();
// [START_EXCLUDE]
// [END_EXCLUDE]
} else {
// Sign in failed, display a message and update the UI
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
// [START_EXCLUDE silent]
// [END_EXCLUDE]
}
// [START_EXCLUDE silent]
// Update UI
// [END_EXCLUDE]
}
}
});
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
// [START verify_with_code]
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
// [END verify_with_code]
signInWithPhoneAuthCredential(credential);
}
private void callback_verificvation() {
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
signInWithPhoneAuthCredential(credential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
// This callback is invoked in an invalid request for verification is made,
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
// The SMS verification code has been sent to the provided phone number, we
// now need to ask the user to enter the code and then construct a credential
// by combining the code with a verification ID.
// Save verification ID and resending token so we can use them later
mVerificationId = verificationId;
mResendToken = token;
}
};
This Exception is thrown because you have connected the email pw login and facebook login together, the google account with same email used in facebook one's is not associated together. As by default, firebase doesn't allow multiple account from same email this collision occurs.
To solve this issue you have two options
1. Link the google account to the facebook and email one's using
mAuth.getCurrentUser().linkWithCredential(credential);
Adding new credential to the existing logged in user.
2. Enable multiple account from same email(not recommended) from the firebase console
This will make new uid for the google logged user and the previous facebook login user will have the old one.

Firebase phone Auth for Android , Can we just verify phone number without creating a user account

I am working on an android app, in where I just want to verify mobile number without creating a user account. Is it Possible? I am using the following code
private void startPhoneNumberVerification(String phoneNumber) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredential(credential); // this function is creating user account , if not present. But We Don't want this
}
The following function will create user account if user account is not there, but I don't want to create account, I just want to verify the code entered by the user. Is there any call back method available for that?
private void signInWithPhoneAuthCredential(final PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
dialog.dismiss();
FirebaseUser user = task.getResult().getUser();
Toast.makeText(LoginActivity.this, "Success " + user.getEmail(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(LoginActivity.this, "Failed ", Toast.LENGTH_SHORT).show();
verifyPhoneNumberWithCode(mVerificationId, editText.getText().toString().trim());
}
}
});
}
You can't verify what the user typed without linking the phone provider to the Firebase user in the process.
But you can unlink the phone from the user account soon after, by calling:
FirebaseAuth.getInstance().getCurrentUser().
unlink(PhoneAuthProvider.PROVIDER_ID)
.addOnCompleteListener(this, onCompleteListener);
There are plenty of uses for verifying that the user has access to this phone number, but shouldn't login with it. I really think that Firebase should allow developers to verify first, and use the credential to login after.
Also:
There is a good chance of Google Play Services verifying automatically. When onVerificationCompleted(PhoneAuthCredential) in your PhoneAuthProvider.OnVerificationStateChangedCallbacks is called. This way the user won't need to type the verification code, and the phone won't be linked automatically.
Verifying a phone number automatically creates a Firebase Authentication account for that user. There is no way to prevent creating this account, as it is what Firebase uses to ensure it knows that user next time they start the app.
You can also update the phone number on the user account.
This will not create new user; instead, it will update the phone number in the existing user account.
val credential = PhoneAuthProvider.getCredential(verificationId!!, smsCode)
FirebaseAuth.getInstance().currentUser?.updatePhoneNumber(credential)

Categories

Resources