so I am using firebase database and Auth, I am trying to build Phone Auth but for some reason the app is crashing.. not sure why..
I am new to programming with android studio and first timer on Firebase database, not sure why the app is crashing but its crashing after I am pressing a button that activate verifySignInCode() insta crash after it, it does send an email with code a
Log cat Error is here
09-15 20:39:41.804 22046-22046/com.example.erelpc.calltest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.erelpc.calltest, PID: 22046
java.lang.IllegalArgumentException: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, ortemprary proof.
at com.google.android.gms.common.internal.Preconditions.checkArgument(Unknown Source:8)
at com.google.firebase.auth.PhoneAuthCredential.<init>(Unknown Source:6)
at com.google.firebase.auth.PhoneAuthProvider.getCredential(Unknown Source:33)
at com.example.erelpc.calltest.MainActivity.verifySignInCode(MainActivity.java:92)
at com.example.erelpc.calltest.MainActivity.access$100(MainActivity.java:28)
at com.example.erelpc.calltest.MainActivity$2.onClick(MainActivity.java:61)
at android.view.View.performClick(View.java:6877)
And Here is the MainActivity
/// SMS Handler
private void sendVerificationCode(){
String phone = etphonenumber.getText().toString();
if (phone.isEmpty()) {
etphonenumber.setError("Enter a Phone Number!");
etphonenumber.requestFocus();
return;
}
if (phone.length() != 9){
etphonenumber.setError("Please Enter a valid Number!");
etphonenumber.requestFocus();
return;
}
phone = "+972" + phone;
Intent intent = new Intent(this, loginsuccess.class);
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phone, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
}
private void verifySignInCode(){
String code = etcodeveri.getText().toString();
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codesent, code);
signInWithPhoneAuthCredential(credential);
}
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
}
#Override
public void onVerificationFailed(FirebaseException e) {
}
#Override
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
codesent = s;
}
};
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "Login Success!", Toast.LENGTH_SHORT).show();
registerModule();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(getApplicationContext(), "Login Unsuccess!", Toast.LENGTH_SHORT).show();
}
}
}
});
}
public void registerModule(){
Intent intent = new Intent(this, loginsuccess.class);
startActivity(intent);
}
The crashing is happening after I press the "btnAdd"
The app is crashing because the method is not getting valid credential for the phoneAuth to work. This can be fixed by using try and catch on the signInWithPhoneAuthCredential() method.
In code it will look something like this:
private void verifyCode(){
String code = cd.getText().toString(); // this is OTP
String pH = phone.getText().toString(); // this is phone number
if(code.equals("") && pH.equals(""))
Toast.makeText(MainActivity.this,"Nothing to validate", Toast.LENGTH_SHORT).show();
else {
try {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(otp, code);
signInWithPhoneAuthCredential(credential);
}
catch (Exception e) {
Log.i("exception",e.toString());
Toast.makeText(MainActivity.this,"Invalid credentials",Toast.LENGTH_LONG).show();
}
}
}
Also, you should put more catch or if statements to avoid giving null value in the methods.
Just need to define String code before calling phoneAuth function.
< String code = phoneAuthCredential.getSmsCode();
assert code != null;
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, code);
signInWithPhoneAuthCredential(credential);>
Related
I want to verify user through phone number verification OTP code, now I am unable to fix this issue. I am new in android App development. I have connected Firebase with android studio, that's all fine except this error.
Logcat message error:
Caused by: java.lang.ClassCastException: com.google.android.gms.tasks.TaskExecutors$zza cannot be cast to android.app.Activity
at com.saqib.onlinefirregistration.VerifyOTP.sendVerificationCodeToUser(VerifyOTP.java:55)
at com.saqib.onlinefirregistration.VerifyOTP.onCreate(VerifyOTP.java:48)
VerifyOTP.java:
public class VerifyOTP extends AppCompatActivity {
//Variable
PinView pinForUser;
String codeBySystem;
Button verifyButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.verify_otp);
pinForUser = findViewById(R.id.pin_view);
verifyButton = findViewById(R.id.verify_btn);
String _PhoneNo = getIntent().getStringExtra("phoneNo");
sendVerificationCodeToUser(_PhoneNo);
}
private void sendVerificationCodeToUser(String phoneNo) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNo, // Phone No to verify
60, //timeout duration
TimeUnit.SECONDS, //Time unit
(Activity) TaskExecutors.MAIN_THREAD,
mCallback);
}
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallback
= new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onCodeAutoRetrievalTimeOut(#NonNull String s) {
super.onCodeAutoRetrievalTimeOut(s);
codeBySystem =s;
}
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
String code = phoneAuthCredential.getSmsCode();
if (code!=null){
pinForUser.setText(code);
verifyCode(code);
}
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
Toast.makeText(VerifyOTP.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
};
private void verifyCode(String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeBySystem,code);
signInWithPhoneAuthCredential(credential);
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
Toast.makeText(VerifyOTP.this, "Verification Completed", Toast.LENGTH_SHORT).show();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(VerifyOTP.this, "Verification Not Completed! Try Again", Toast.LENGTH_SHORT).show();
}
}
}
});
}
private void signInUsingCredential(PhoneAuthCredential credential) {
}
public void callNextScreenOTP( View view) {
String code = pinForUser.getText().toString();
if (!code.isEmpty()) {
verifyCode(code);
}
}
};
How can I fix this issue? I have no idea about it, I did search for the same question but failed to find on Google, or stack overflow.
I want to verify user through phone number verification OTP code, now I am unable to fix this issue. I am new in android App development. I have connected Firebase with android studio, that's all fine except this error.
(Activity) TaskExecutors.MAIN_THREAD line is wrong. It's clear from the error message that the cast cannot be made.
Since you're in activity, just this should do it in this place.
Just Replace: (Activity) TaskExecutors.MAIN_THREAD,
With: this,
I am trying to create a phone number logging section in my application so that the user can log in using the phone number. I am trying to run my application on the physical device when I try to login using the phone number and received an error says the null reference. I have searched for the solution all over the internet but didn't get any proper solution to remove this error. I have allowed the phone authentication in firebase still, I am getting the error. I have used the country picker in my activity to get the country code and it works file.
Error occurs in
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phonestring,
60,
TimeUnit.SECONDS,
Phoneactivity.this,
mCallbacks
);
Phoneactivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phoneactivity);
mAuth = FirebaseAuth.getInstance();
initalization();
phonenumbermethod();
emailloginmethod();
}
private void emailloginmethod() {
emaillogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),Loginactivity.class);
startActivity(intent);
}
});
}
private void phonenumbermethod() {
if(REQUEST.equals("phone")){
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
REQUEST = "OTP";
String phonenumberstring = phone.getText().toString();
String countrycode = ccp.getSelectedCountryCodeWithPlus();
phonestring = countrycode + phonenumberstring;
//Toast.makeText(getApplicationContext(),phonestring,Toast.LENGTH_SHORT).show();
verificationcodesend();
}
});
}else{
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
REQUEST = "phone";
otpstring = otp.getText().toString();
otpmethod();
}
});
}
}
private void otpmethod() {
if (TextUtils.isEmpty(otpstring)){
Toast.makeText(getApplicationContext(),"Please enter the verification code", Toast.LENGTH_SHORT).show();
}else{
loadingBar.setTitle("Verification code");
loadingBar.setMessage("Please wait...");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, otpstring);
signInWithPhoneAuthCredential(credential);
}
}
private void verificationcodesend() {
if(TextUtils.isEmpty(phonestring)){
Toast.makeText(getApplicationContext(),"Please enter phone number",Toast.LENGTH_SHORT).show();
}else{
loadingBar.setTitle("Phone verification");
loadingBar.setMessage("Please wait till we verify your account");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
Log.i("phoneactivity",phonestring);
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phonestring,
60,
TimeUnit.SECONDS,
Phoneactivity.this,
mCallbacks
);
}
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
loadingBar.dismiss();
Toast.makeText(getApplicationContext(),"Please enter the correct phone number", Toast.LENGTH_SHORT).show();
}
#Override
public void onCodeSent(#NonNull String verificationId,
#NonNull PhoneAuthProvider.ForceResendingToken token) {
loadingBar.dismiss();
mVerificationId = verificationId;
mResendToken = token;
Toast.makeText(getApplicationContext(),"Verification code has been send", Toast.LENGTH_SHORT).show();
otpnumber.setVisibility(View.VISIBLE);
phonenumber.setVisibility(View.GONE);
}
};
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
loadingBar.dismiss();
sendusertomainActivity();
Toast.makeText(getApplicationContext(),"welcome",Toast.LENGTH_SHORT).show();
} else {
String msg = task.getException().toString();
Toast.makeText(getApplicationContext(),"Error: "+ msg, Toast.LENGTH_SHORT).show();
}
}
});
}
private void sendusertomainActivity() {
Intent intent = new Intent(getApplicationContext(),HomeActivity.class);
startActivity(intent);
}
error: null reference
java.lang.NullPointerException: null reference
at com.google.android.gms.common.internal.Preconditions.checkNotNull(Unknown Source:2)
at com.google.firebase.auth.PhoneAuthProvider.verifyPhoneNumber(com.google.firebase:firebase-auth##19.2.0:9)
at com.nanb.Alpha.Phoneactivity.verificationcodesend(Phoneactivity.java:109)
at com.nanb.Alpha.Phoneactivity.access$300(Phoneactivity.java:28)
at com.nanb.Alpha.Phoneactivity$2.onClick(Phoneactivity.java:72)
at android.view.View.performClick(View.java:6608)
at android.view.View.performClickInternal(View.java:6585)
at android.view.View.access$3100(View.java:785)
at android.view.View$PerformClick.run(View.java:25921)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6864)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
update
2020-03-15 21:03:00.382 30384-30384/com.nanb.Alpha I/phoneactivity: +919771553694
You're not initializing mCallback before passing it into verifyPhoneNumber, which is what the null check is complaining about.
To fix it, move the mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {... before the call to verifyPhoneNumber.
I am trying to set up OTP verification
I have already tried many possibilities with the if and else, however, it didn't help out.
public class userLogin extends Activity {
EditText phnNum=null, veri = null;
FirebaseAuth au;
Button forgotpass, login;
PhoneAuthProvider.OnVerificationStateChangedCallbacks otp;
String verifyCode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.userlogin);
login = findViewById(R.id.loginButton);
phnNum = findViewById(R.id.enter_phone);
forgotpass = findViewById(R.id.forgot_pass);
au = FirebaseAuth.getInstance();
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ((phnNum.getText().toString()).equals("")) {
(Toast.makeText(getApplicationContext(), "Please enter the phone number and proceed to receive an OTP", Toast.LENGTH_SHORT)).show();
}
else{
otp = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
}
#Override
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
verifyCode = s;
(Toast.makeText(getApplicationContext(), "The OTP Code has been send, please verify the code", Toast.LENGTH_SHORT)).show();
}
};
}
}
});
}
public void send_sms (View v){
String i = (phnNum.getText()).toString();
PhoneAuthProvider.getInstance().verifyPhoneNumber(i, 60, TimeUnit.SECONDS, this, otp);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent u = new Intent(view.getContext(), otp_verify.class);
startActivity(u);
}
});
}
//SignIn Method
// We will pass value in the method with "PhoneAuthCredential" data-type.
public void SignIn(PhoneAuthCredential credential) {
//" au " is the firebase variable and call the method
au.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
(Toast.makeText(getApplicationContext(), "You have Sign-In Successfully", Toast.LENGTH_SHORT)).show();
}
else{
(Toast.makeText(getApplicationContext(), "Please try again", Toast.LENGTH_SHORT)).show();
}
}
});
}
}
When I log-in with blank EditText, the if part executes but when I enter the phone number it doesn't execute the else part. I expect the when the user enters their phone number the else part should execute.
final String i = (phnNum.getText()).toString();
if ("".equals(i)) {
(Toast.makeText(getApplicationContext(), "Please enter the phone number and proceed to receive an OTP", Toast.LENGTH_SHORT)).show();
} else {
// 1. prepare callback for async call
otp = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
}
#Override
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
verifyCode = s;
(Toast.makeText(getApplicationContext(), "The OTP Code has been send, please verify the code", Toast.LENGTH_SHORT)).show();
Intent u = new Intent(userLogin.this, otp_verify.class);
startActivity(u);
}
};
// 2. execute actual call
PhoneAuthProvider.getInstance().verifyPhoneNumber(i, 60, TimeUnit.SECONDS, userLogin.this, otp);
}
The code snippet prepares callback and uses it on Firebase auth call. When the verification code is actually sent, the onCodeSent called and new activity launched.
So I had my Phone Verify working since I updated my Firebase last week. Since then I'm facing the problem that in my linking process where I'm connecting the users email to the phone number doesn't work anymore:
java.lang.IllegalArgumentException: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, ortemprary proof.
I've seen some users with the same problem but nobody with a solution.
I tried to rewrite the whole Code but the problem is still there. Has Firebase changed something in the linking process?
As I have seen in the Firebase Linking Documentation, the section about Phone Number linking was removed.
Is something wrong with my code or is it a problem with firebase?
Firebase Versions I'm using:
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-messaging:17.6.0'
implementation 'com.google.firebase:firebase-perf:16.2.5'
implementation 'com.android.support:support-compat:28.0.0'
implementation 'com.google.firebase:firebase-auth:16.2.1'
implementation 'com.google.firebase:firebase-storage:16.1.0'
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_phone_verify);
Log.e("PhoneVerify","Start");
mAuth = FirebaseAuth.getInstance();
editTextCode = findViewById(R.id.editTextCode);
editTextPhone = findViewById(R.id.editTextPhone);
Bundle extras = getIntent().getExtras();
if (extras !=null) {
final String phone = extras.getString("phone");
Log.e("Phone(Extras):",phone);
editTextPhone.setText(phone);
sendVerificationCode(phone);
}
findViewById(R.id.buttonGetVerificationCode).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String phone = editTextPhone.getText().toString().trim();
if (phone.isEmpty() || phone.length() < 10) {
editTextPhone.setError("Phone number error");
editTextPhone.requestFocus();
return;
}
sendVerificationCode(phone);
}
});
findViewById(R.id.buttonSignIn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
verifyVerificationCode(editTextCode.getText().toString());
}
});
}
private void sendVerificationCode(String phonenumber) {
String phone = "+14" + phonenumber;
Log.e("sendVerificationCode",phone);
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phone, // Phone number to verify
60, // Timeout duration
TimeUnit.SECONDS, // Unit of timeout
this, // Activity (for callback binding)
mCallbacks); // OnVerificationStateChangedCallbacks
}
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
//Getting the code sent by SMS
final String code = phoneAuthCredential.getSmsCode();
if (code != null) {
editTextCode.setText(code);
//verifying the code
verifyVerificationCode(code);
Log.e("onVerificationCompleted",code);
}
}
#Override
public void onVerificationFailed(FirebaseException e) {
Log.e("onVerificationFailed", String.valueOf(e));
}
#Override
public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
Log.e("onCodeSent", "Code Sent");
codeSent = s;
PhoneAuthProvider.ForceResendingToken mResendToken = forceResendingToken;
}
};
private void verifyVerificationCode(String code) {
//creating the credential
try {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent, code);
linkWithCredential(credential,code);
} catch (Exception e) {
Log.e("Exception", String.valueOf(e));
}
Log.e("VerifyCode CHECKP",code);
//signing the user
}
private void linkWithCredential(final AuthCredential credential, final String code) {
mAuth.getCurrentUser().linkWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.e("Linking Phone to Email","Successfull");
try {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeSent, code);
signInWithPhoneAuthCredential(credential);
} catch (Exception e) {
Log.e("Exception", String.valueOf(e));
}
}
});
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(PhoneVerify.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//verification successful we will start the profile activity
Log.e("FINAL LINK","DONE");
} else {
//verification unsuccessful.. display an error message
String message = "Somthing is wrong, we will fix it soon...";
});
}
}
Here how to use Firebase Phone Authentication from Firebase docs
https://firebase.google.com/docs/auth/android/phone-auth
and linking Authentication provider
https://firebase.google.com/docs/auth/android/account-linking
//please notice, mCallback.onVerificationCompleted will automatically called
//if verification code already send to your phone
//(Maybe not called in some case)
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
linkPhoneAuthToCurrentUser(credential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
//show error
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
//save id and token in case you need to resend verification code
}
};
//call this to send verification code
//parameter include country code
private void sendVerificationCode(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
}
//link auth with credential
private void linkPhoneAuthToCurrentUser(PhoneAuthCredential credential) {
FirebaseAuth.getInstance().getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//link auth success update ui
} else {
//link auth failed update ui
}
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_phone_verify);
//init view
//get phone number
String phoneNumb = "Add Your Phone Number Here"
sendVerificationCode(phoneNumb)
//if mCallback not called,
//use this button to sign in with manual input verification code
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//get verification id from mCallback.onCodeSent
//get verificationCode manually from edittext
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, verificationCode);
linkPhoneAuthToCurrentUser(credential);
}
});
}
PS : you need to re-authenticate your email authentication before link phone number authentication. Follow this link to re-authenticate https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user
onVerificationCompleted is called when firebase automatically verifies the phone number by detecting the sms code sent to the phone.
I think you should reformat your code to either use only the credential here, or the one you generate manually by combination of the code entered by the user and verificationId; and not both.
Also no need to sign in again with phone credential, you already signed in
I mean you should have something like this instead,
private void linkWithCredential(final PhoneAuthCredential credential) {
mAuth.getCurrentUser().linkWithCredential(credential).addOnComplete.......{
onComplete(....) {
.....
//signInWithPhoneCredential(credential);
// You Already signed in. No need. Just update the ui with the user info
}
https://firebase.google.com/docs/auth/android/account-linking
I have followed the guideline of firebase docs to implement login into my app but there is a problem while signup, the app is crashing and the catlog showing the following erros :
Process: app, PID: 12830
java.lang.IllegalArgumentException: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, ortemprary proof.
at com.google.android.gms.common.internal.Preconditions.checkArgument(Unknown Source)
at com.google.firebase.auth.PhoneAuthCredential.<init>(Unknown Source)
at com.google.firebase.auth.PhoneAuthProvider.getCredential(Unknown Source)
at app.MainActivity.verifyPhoneNumberWithCode(MainActivity.java:132)
at app.MainActivity.onClick(MainActivity.java:110)
at android.view.View.performClick(View.java:4803)
at android.view.View$PerformClick.run(View.java:20102)
at android.os.Handler.handleCallback(Handler.java:810)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5532)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
I've tried to see other code examples but they are simmiler to my code but still my app crashes with the same error.
and this is my code i wrote using the guidline of firebase documents :
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private FirebaseAuth mAuth;
private String mVerificationId;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
Button login,verify,signout;
EditText number;
EditText code;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
login = findViewById(R.id.btnlogin);
verify = findViewById(R.id.btnverify);
signout = findViewById(R.id.btnsignout);
number = findViewById(R.id.editnumber);
code = findViewById(R.id.editcode);
login.setOnClickListener(this);
verify.setOnClickListener(this);
signout.setOnClickListener(this);
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(MainActivity.this, "Error" + e.toString(), Toast.LENGTH_SHORT).show();
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(MainActivity.this, "Invalid Request " + e.toString(), Toast.LENGTH_SHORT).show();
} else if (e instanceof FirebaseTooManyRequestsException) {
Toast.makeText(MainActivity.this, "The SMS quota for the project has been exceeded " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCodeSent(String vId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
Toast.makeText(MainActivity.this, "Code Sent" + vId, Toast.LENGTH_SHORT).show();
number.setText("");
mVerificationId = vId;
}
};
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential phoneAuthCredential) {
mAuth.signInWithCredential(phoneAuthCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isComplete()){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String uid = null;
if (user != null) {
uid = user.getUid();
}
Toast.makeText(MainActivity.this, "Signed In", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, uid, Toast.LENGTH_SHORT).show();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(MainActivity.this, "Invalid Code", Toast.LENGTH_SHORT).show();
}
}
}
});
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnlogin: {
String phonenumber = number.getText().toString();
startPhoneNumberVerification(phonenumber);
}
case R.id.btnverify: {
String vCode = code.getText().toString();
verifyPhoneNumberWithCode(mVerificationId, vCode);
}
case R.id.btnsignout: {
mAuth.signOut();
}
}
}
private void startPhoneNumberVerification(String phoneNumber) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(phoneNumber, 60, TimeUnit.SECONDS, this, mCallbacks);
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredential(credential);
}
}
The Above code is sending the otp to the given number but it crashes and cat-log shows the error mentioned above.
Please try to help me to figure out what is the error in my code rather referring to other codes.
you are getting number without country code like +91 use with country code or use
String withCountryCode = "+91"+code
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, withCountryCode);
signInWithPhoneAuthCredential(credential);