i'm now making android apps, so here is my VerifyOTP class , I'm getting E/zzbf: SafetyNet Attestation fails basic integrity. error ...
Can Someone please help me .
this SafetyNet I just can't understand...
I've tried everything, the aplication should automatically entered Code given by SMS ... but when I enter my information in aplication, my phone number is passed by Intent ... end used in sendVerificationCodeToUser()...
public class VerifyOTP extends AppCompatActivity {
// Variables
PinView pinFromUser;
ImageView closeBtn;
String codeBySystem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_verify_o_t_p);
// Hooks
pinFromUser = findViewById(R.id.pin_view);
closeBtn = findViewById(R.id.otp_close_btn);
String _phoneNo = getIntent().getStringExtra("phone");
sendVerificationCodeToUser(_phoneNo);
closeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
VerifyOTP.super.onBackPressed();
}
});
}
private void sendVerificationCodeToUser(String phone) {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber(phone) // 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 PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks =
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
codeBySystem = s;
}
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
String code = phoneAuthCredential.getSmsCode();
if (code != null) {
pinFromUser.setText(code);
verifyCode(code);
}
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
Toast.makeText(VerifyOTP.this, e.getMessage(), Toast.LENGTH_LONG).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 failed!", Toast.LENGTH_SHORT).show();
}
}
}
});
}
public void CallNextFromOTP(View view) {
String code = pinFromUser.getText().toString();
if (!code.isEmpty()) {
verifyCode(code);
}
}
}
did you add at AndroidManifest.xml these permissions ?
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
i think because your code is missing premission check function that's why send you to navigation add this code to your code in VerifyOTP.java
private void checkForSmsPermission() {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.SEND_SMS) !=
PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, getString(R.string.permission_not_granted));
// Permission not yet granted. Use requestPermissions().
// MY_PERMISSIONS_REQUEST_SEND_SMS is an
// app-defined int constant. The callback method gets the
// result of the request.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS},
MY_PERMISSIONS_REQUEST_SEND_SMS);
} else {
// Permission already granted. Enable the SMS button.
enableSmsButton();
}
}
Add these dependencies in your build.gradle :
implementation "androidx.browser:browser:1.3.0"
implementation "com.google.firebase:firebase-messaging:21.1.0"
Firebase Quote "The reCAPTCHA flow will only be triggered when SafetyNet is unavailable or your device does not pass suspicion checks. Nonetheless, you should ensure that both scenarios are working correctly." So to enable SafetyNet, follow the below steps or you can also visit Firebase Auth for more info.
Go to google cloud console, select your project.
Click on the navigation menu and select APis & services and then select Dashboard.
Click on enable api and services and enable api " Android Device Verification".
Add SHA 256 in firebase project settings.(debug and release both)
Download and replace the latest google-services.json file in your project.
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,
Edit: It has been solved.
This question is not similar to previous ones. I have referred to
app crash while using firebase phone Auth in android but my app is still crashing.
So I am trying to design a chat app where the user can login with OTP provided by Firebase but when I enter the OTP(right/wrong) received on phone the app crashes. If someone can please guide me it'll be fantastic.
Note: I have included the implementation "androidx.browser:browser:1.3.0" dependency but the app is still crashing when I try to verify the OTP
The main error I am getting is
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.commutify, PID: 5168
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
at com.example.commutify.otpAuthentication$2.onClick(otpAuthentication.java:61)
at android.view.View.performClick(View.java:6647)
at android.view.View.performClickInternal(View.java:6620)
at android.view.View.access$3100(View.java:791)
at android.view.View$PerformClick.run(View.java:26346)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7081)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:928)
So here is my code for class where OTP Authentication takes place
TextView mchangenumber;
EditText mgetotp;
android.widget.Button mverifyotp;
String enteredotp;
FirebaseAuth firebaseAuth;
ProgressBar mprogressbarofotpauth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_otp_authentication);
mchangenumber = findViewById(R.id.changenumber);
mverifyotp = findViewById(R.id.verifyotp);
mgetotp = findViewById(R.id.getotp);
mprogressbarofotpauth = findViewById(R.id.progressbarofmain);
firebaseAuth = FirebaseAuth.getInstance();
mchangenumber.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(otpAuthentication.this, MainActivity.class);
startActivity(intent);
}
});
mverifyotp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
enteredotp = mgetotp.getText().toString();
if(enteredotp.isEmpty()){
Toast.makeText(getApplicationContext(), "Enter Your OTP First", Toast.LENGTH_SHORT).show();
}
else{
mprogressbarofotpauth.setVisibility(View.VISIBLE);
String coderecieved = getIntent().getStringExtra("otp");
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(coderecieved, enteredotp);
signInWithPhoneAuthCredential(credential);
}
}
});
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
firebaseAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull #org.jetbrains.annotations.NotNull Task<AuthResult> task) {
if (task.isSuccessful()) {
mprogressbarofotpauth.setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(otpAuthentication.this, setProfile.class);
startActivity(intent);
finish();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
mprogressbarofotpauth.setVisibility(View.INVISIBLE);
Toast.makeText(getApplicationContext(), "Login Failed!", Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
Here are my gradle dependencies
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.browser:browser:1.3.0"
implementation 'com.google.firebase:firebase-auth:21.0.1'
implementation 'com.google.firebase:firebase-database:20.0.1'
implementation 'com.google.firebase:firebase-firestore:23.0.3'
implementation 'com.google.firebase:firebase-storage:20.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.intellij:annotations:+#jar'
implementation 'com.hbb20:ccp:2.5.1'
}
If someone wants the MainActivity where I enter the number for verification here it is
public class MainActivity extends AppCompatActivity {
EditText mgetphonenumber;
android.widget.Button msendotp;
CountryCodePicker mcountrycodepicker;
//extra m is added for for easily assigning XML ID to Java ID
String countrycode;
String phonenumber;
FirebaseAuth firebaseAuth;
ProgressBar mprogressbarofmain;
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
String codesent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mcountrycodepicker = findViewById(R.id.countrycodepicker);
msendotp = findViewById(R.id.sendotpbutton);
mgetphonenumber = findViewById(R.id.getphonenumber);
mprogressbarofmain = findViewById(R.id.progressbarofmain);
firebaseAuth = FirebaseAuth.getInstance();
countrycode = mcountrycodepicker.getSelectedCountryCodeWithPlus();
//below segment is for those who want to change their countries
mcountrycodepicker.setOnCountryChangeListener(new CountryCodePicker.OnCountryChangeListener() {
#Override
public void onCountrySelected() {
countrycode = mcountrycodepicker.getSelectedCountryCodeWithPlus();
}
});
//for sending otp
msendotp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number;
number = mgetphonenumber.getText().toString();
//if the user doesn't enters the number
if(number.isEmpty()){
Toast.makeText(getApplicationContext(), "Please Enter Your Number", Toast.LENGTH_SHORT).show();
}
//since a number has 10 digits
else if(number.length()<10){
Toast.makeText(getApplicationContext(), "Please Enter a Valid Number", Toast.LENGTH_SHORT).show();
}
else{
mprogressbarofmain.setVisibility(View.VISIBLE);
//concatenates country code and the number added by the user
phonenumber = countrycode + number;
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(firebaseAuth)
.setPhoneNumber(phonenumber)
.setTimeout(60L, TimeUnit.SECONDS)
.setActivity(MainActivity.this)
.setCallbacks(mCallbacks)
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
}
});
//function to verify the number for otp
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
//how to automatically fetch OTP(for future)
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
}
#Override
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
//if the function runs successfully, the code is sent
Toast.makeText(getApplicationContext(), "OTP is Sent", Toast.LENGTH_SHORT).show();
mprogressbarofmain.setVisibility(View.INVISIBLE);
codesent = s;
Intent intent = new Intent(MainActivity.this, otpAuthentication.class);
intent.putExtra("otp", codesent);
startActivity(intent);
}
};
}
//for checking if the user exists(in order to open the chat screen)
#Override
protected void onStart() {
super.onStart();
if(FirebaseAuth.getInstance().getCurrentUser()!=null){
Intent intent = new Intent(MainActivity.this, chatscreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
}
It looks like a problem not related to Firebase.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
Are you sure your progress bar is initialized? Maybe findViewById doesn't do what it needs to do? Maybe on layout, progressbar view id not same?
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'm finished with android app. Used firebase, admob. Has 31 activities. But when user installs the app for first time, the launch time is approximately 18 seconds which is too high. After first time launching, signup activity is there. But if we relaunch the app then it launches in 2 seconds. Why there is very high launch time? How can I reduce it? Below is my Sign up activity code. Using android studio 2.2
public class MainActivity extends AppCompatActivity {
private AdView mAdView;
private SignInButton mGoogleBtn;
private static final int RC_SIGN_IN=1;
private GoogleApiClient mGoogleApiClient;
private FirebaseAuth mAuth;
private static final String TAG="MAIN_ACTIVITY";
private FirebaseAuth.AuthStateListener mAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth=FirebaseAuth.getInstance();
mAuthListener=new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if(firebaseAuth.getCurrentUser()!=null){
startActivity(new Intent(MainActivity.this,Home.class));
}
}
};
mGoogleBtn=(SignInButton)findViewById(R.id.view);
// Configure Google Sign In
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleApiClient=new GoogleApiClient.Builder(getApplicationContext())
.enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(MainActivity.this,"Login via Google Failed! Press Skip",Toast.LENGTH_LONG).show();
}
})
.addApi(Auth.GOOGLE_SIGN_IN_API,gso)
.build();
mGoogleBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signIn();
}
});
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthWithGoogle(account);
} else {
// Google Sign In failed, update UI appropriately
// ...
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount account) {
Log.d(TAG, "firebaseAuthWithGoogle:" + account.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Log.w(TAG, "signInWithCredential", task.getException());
Toast.makeText(MainActivity.this, "Authentication failed. Press Skip.",
Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(MainActivity.this,"Login Successful! Welcome to Unipune Buddy!",Toast.LENGTH_LONG).show();
}
// ...
}
});
}
private void signIn() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
public void mainscreen(View view){
Intent intent0=new Intent(this,Home.class);
Toast.makeText(MainActivity.this,"Signed in Successfully!",Toast.LENGTH_LONG).show();
startActivity(intent0);
}
}
I too had this issue, what i had done was disabling instant run in the project settings, and rebuilding the project, You can also use Cold start for engaging the user for the first time.
I want my app's users be able to cancel a Firebase Sign-In process while it is running. But I don't see straight handlers for that in the Firebase SDK. The Sign-In methods return Task<AuthResult>, which are not cancelable. What is the best approach I can use to provide a cancellation? Is there a better way than to elaborate extra cancelable async tasks?
My code is quite the same as in the firebase's guide.
public class LoginActivity extends AppCompatActivity{
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mFirebaseAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
onSignIn();
} else {
// User is signed out
onSignOut();
}
// ...
}
};
}
private void signIn(String email, String password){
mFirebaseAuth
.signInWithEmailAndPassword(email, password) // returns noncancelable Task<AsyncResult>
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Toast.makeText(EmailPasswordActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
// ...
}
});
}
#Override
public void onStart() {
super.onStart();
mFirebaseAuth.addAuthStateListener(mFirebaseAuthListener);
}
#Override
protected void onStop() {
super.onStop();
if (mFirebaseAuthListener != null) {
mFirebaseAuth.removeAuthStateListener(mFirebaseAuthListener);
}
}
}