I have a firebase project which allows users to login only if they are already exists in identifier in authentication .
I already added few users using my web app with mobile numbers.
Now, in android I have used the signInWithPhoneAuthCredential method to get the users login.
But in this method, it allows any users to login even if the user is first time entering the mobile number.
Is there any method to restrict this ?
Sample Code :
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
Log.d(TAG, "signInWithCredential:success");
FirebaseUser user = task.getResult().getUser();
// ...
} else {
// Sign in failed, display a message and update the UI
Log.w(TAG, "signInWithCredential:failure", task.getException());
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
// The verification code entered was invalid
}
}
}
});
}
According to the docs:
signInWithPhoneNumber:
Asynchronously signs in using a phone number. This method sends a code via SMS to the given phone number, and returns a firebase.auth.ConfirmationResult. After the user provides the code sent to their phone, call firebase.auth.ConfirmationResult.confirm with the code to sign the user in.
This is the default behavior in all applications that uses phone number as login. There is no method in the firebase docs that can restrict this.
you have to use firebase database also with this code to save user info, that way you can achieve your use case
Related
I have account admin and another account want to reset password, with process like this,
User A reset password > send email to admin > admin reset password > admin send new password to user A (with email)> user A login with new password from Admin.. Can I do like this, tell me example source code java. Thanks
resetPass.setOnClickListener(view -> {
String userMail = resetEmail.getText().toString();
if (TextUtils.isEmpty(userMail)) {
Toast.makeText(ForgotPassActivity.this, "Please write your valid address first", Toast.LENGTH_SHORT).show();
}
else {
auth.sendPasswordResetEmail(userMail).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(ForgotPassActivity.this, "Please check your email account", Toast.LENGTH_SHORT).show();
startActivity(new Intent(ForgotPassActivity.this, Log_inActivity.class));
} else {
Toast.makeText(ForgotPassActivity.this, "Email not found, please try again.", Toast.LENGTH_SHORT).show();
}
}
});
}
});
Firebase Authentication only allows sending a password reset email to the currently signed in user. You can't send a password reset email to another user, as that would open the system up to abuse.
To implement the flow you describe, you'll need to implement your own email sending, and password reset. You can use the Firebase Admin SDK to handle the Firebase aspects of it (get the user, update password), but will need to find another system to send email, and implement your own verification code.
From the title, you would think that there is a published solution to my problem, but in fact I believe I read everything pertinent to my question, but nothing quite matched up. Here's what I've got:
First of all, this problem has never happened in my app before today, nor did my sign-in change in any way: same Google sign-in code, same account. Everything the same for the past three months, as long as I've been testing. And, as far as I can tell, the problem only occurs with a single account. When the user begins the sign-in process, they are presented with a choice of accounts to sign in with; in this case, I selected the first user:
Next, Google authenticates the user and we arrive here in the code:
So the question is, why did Firebase suddenly stop providing the display name (and the photo URL)? From the first screenshot, it's clear that the user has a specified name and photo. Apart from that, FirebaseAuth.getInstance().getCurrentUser().isAnonymous() is false, as expected. Any ideas on why this suddenly broke would be greatly appreciated!
I solved the problem by simply updating my name and photo URL using UserProfileChangeRequest() and the name and photo URL of my Google account, as suggested here:
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
sendFirebaseEvent(FIREBASE_GOOGLE_AUTH_EVENT, FIREBASE_GOOGLE_AUTH_KEY, acct.getId());
// [START_EXCLUDE silent]
showProgressDialog();
googleAccount = acct;
// [END_EXCLUDE]
final AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
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
sendFirebaseEvent(FIREBASE_GOOGLE_AUTH_EVENT, FIREBASE_GOOGLE_AUTH_RESULT_KEY, "Success");
launchNextActivity();
} else {
// If sign in fails, display a message to the user.
sendFirebaseEvent(FIREBASE_GOOGLE_AUTH_EVENT, FIREBASE_GOOGLE_AUTH_RESULT_KEY, task.getException().getMessage());
Snackbar.make(findViewById(R.id.main_layout), "Authentication Failed.", Snackbar.LENGTH_SHORT).show();
updateUI(null);
}
// [START_EXCLUDE]
hideProgressDialog();
// [END_EXCLUDE]
}
});
}
private void launchNextActivity() {
mFirebaseAuth = FirebaseAuth.getInstance();
FirebaseUser mUser = mFirebaseAuth.getCurrentUser();
if (mUser.getDisplayName() == null || mUser.getDisplayName().length() == 0) {
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(googleAccount.getDisplayName())
.setPhotoUri(googleAccount.getPhotoUrl())
.build();
mUser.updateProfile(profileUpdates);
}
}
I want to add a feature in my app that allows the admin account to delete firebase user accounts from inside the app. I have the user Id that I want to delete stored in a String but can't get the user record from the firebase auth database using the Id.
The getUser() method stays in red and android studio shows a note :
Cannot resolve method getUser(java.lang.String).
I already tried searching on the net for previous similar problems but they were all trying to delete the connected user and not a specific user of a given ID
// getIntent() is a method from the started activity
Intent myIntent = getIntent(); // gets the previously created intent
final String UserId = myIntent.getStringExtra("uid"); // will return "User Id"
final Button btnDelete = findViewById(R.id.deleteaccount);
final FirebaseUser userToDelete = FirebaseAuth.getInstance().getUser(UserId);
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
userToDelete.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(TAG, "Account deleted", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(TAG, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
})
}
});
I want to achieve one goal: Being able to delete a user with a given Id.
The Firebase web and mobile client libraries don't support the ability to get and delete user accounts, as that would pose a security risk. The only way to programmatically manage user accounts is using the Firebase Admin SDK to on a backend you control.
I want to generate and store token everytime users login. I tried for my code below, but it always generate same token when I login with another account.
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
AlertDialog.dismiss();
if (!task.isSuccessful()) {
if (password.length() < 6) {
new SweetAlertDialog(LoginActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText("Enter minimum 6 charachters !! ")
.show();
} else {
passwordInput.setText("");
new SweetAlertDialog(LoginActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("Oops...")
.setContentText("Authentication failed !!")
.show();
}
} else {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
FirebaseUser users = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("users/"+ users.getUid());
String token = FirebaseInstanceId.getInstance().getToken();
Log.e("tokenid",""+token);
mDatabase.child("token_id").setValue(token);
finish();
}
}
});
}
});
please help, thanks..
When using the following line of code:
String token = FirebaseInstanceId.getInstance().getToken();
You are getting the Firebase Instance ID token, which is also known as FCM token, on the client side. You need to know that in Firebase there two different tokens:
A FCM Token/Instance ID token that identifies an installation of a specific application on a specific user device. It doesn't identify in any way a particular user.
An Auth ID token identifies a specific user of a specific application. It doesn't identify in any way a particular device.
The two tokens are quite different and serve different purposes. Please see the official documentation for Android regarding on how to retrieve ID tokens on clients.
The identity of the user is remembered indefinitely (or until you sign out). But their credentials (or rather, whether their token is still valid) are re-checked every hour.
FCM generates a registration token for the client app instance, hence It may happen that you'll get the same token for different users in your app. You can use forceRefresh to generate a new token every time. Register new token everytime user logins to any device and save it in DB and update with a new token on new login this way you will have a new token for each user on every login (If this fits your requirement)
Here is a good answer to understand how it works Firebase FCM force onTokenRefresh() to be called
Use UUID.randomUUID().toString()
You can read more here.
java docs - and here =)
So I know I can use email verification, or phone number verification, but what I want to do is a phone number verification after the user has registered or logged in. How do you connect this these two authentication methods. Finally, is there a function in Firebase to check if the user is verified by phone number or not? Thank you.
You can still use the APi provided by firebase to verify the number even if the user is authenticated. According to the docs , the authentication happens only when the user receives the confirmation code and generates a PhoneAuthCredential. If you just want to vrify the phone you can simply provide a custom reaction to the callback onVerificationCompleted.
Normally you set up the provider:
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber,
60,
TimeUnit.SECONDS,
this,
mCallbacks);
And you implement a series of callbacks.
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
//No need to authenticate again, just react to verified number
//signInWithPhoneAuthCredential(credential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
if (e instanceof FirebaseAuthInvalidCredentialsException) {
} else if (e instanceof FirebaseTooManyRequestsException) {
}
}
#Override
public void onCodeSent(String verificationId,
PhoneAuthProvider.ForceResendingToken token) {
mVerificationId = verificationId;
mResendToken = token;
}
};
According to your second question about to verify how the user is signed in you can check this answer to see how to check the firebase user authentication providers.
When a user is logged in you can get its phone number (if there is any) by calling:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String number = user.getPhoneNumber();