I have used Firebase serval times by now and I am aware to how use it correctly.
I believe I have been stumble on a bug and would love to hear a solution in case you have one.
So - I used Firebase Google auth and it worked ok, then I decided to use the email + password method.
Now this is the weird part - I create a user, I get successful result but it doesn't save the user - cant see it in the Autherecation panel + cant sign in with the user after I sign out.
mLoginContainer.setVisibility(View.GONE);
mLoginProgress.setVisibility(View.VISIBLE);
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful())
Toast.makeText(LoginActivity.this,"",Toast.LENGTH_SHORT).show();
else
Toast.makeText(LoginActivity.this,"",Toast.LENGTH_SHORT).show();
mLoginContainer.setVisibility(View.VISIBLE);
mLoginProgress.setVisibility(View.GONE);
}
});
You need to enable E-mail/Password on firebase console.
Click here for Firebase Auth Doc
How to enable E-mail/password sign-in:
In the Firebase console, open the Auth section.
On the Sign in method tab, enable the Email/password sign-in method and click Save.
hope it helps
Refer this
Hope you have added compile 'com.google.firebase:firebase-auth:9.2.1'in gradle dependencies
Enabling Email/Password Authentication
Go to your firebase panel.
On the left side menu you will see Auth, click on it.
Now click on Set Up Sign In Method.
Now click on Email/Password, enable it and press save.
For SignUp
In your Registration activity
//defining firebaseauth object
private FirebaseAuth firebaseAuth;
onCreate
//initializing firebase auth object
firebaseAuth = FirebaseAuth.getInstance();
//after the successful validation of username and password[call your registration method with following)
//creating a new user
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
//checking if success
if(task.isSuccessful()){
//display some message here
Toast.makeText(this,"Successfully registered",Toast.LENGTH_LONG).show();
}else{
//display some message here
Toast.makeText(this,"Registration Error",Toast.LENGTH_LONG).show();
}
progressDialog.dismiss();
}
});
Click on Signup button in your design and if you got the success message. Check your firebase console.
For SignIn
mAuth.signInWithEmailAndPassword(strUsrL,strPassL)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
progressBar.setVisibility(View.GONE);
if(task.isSuccessful()){
Toast.makeText(this, "Successfully Login", Toast.LENGTH_SHORT).show();
}
}})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
Log.e("EXCEPTION",e.getLocalizedMessage().toString());
}
});
Reinstall application in emulator and try to provide an emulator with play store installation
Related
When I am trying to sign up a user using Firebase authentication method in my Android application, this is happening:
It's not registering a user
This is the Registration code
final String _name = txtName.getText().toString().trim();
String _email = txtEmail.getText().toString().trim();
String _pass = txtPass.getText().toString().trim();
if(!TextUtils.isEmpty(_name) && !TextUtils.isEmpty(_email) && !TextUtils.isEmpty(_pass) ) {
mProgress.setMessage("Registrando ...");
mProgress.show();
firAuth.createUserWithEmailAndPassword(_email, _pass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()) {
//the user has been registered
}
}
});
You are registring the user but not hiding the progress bar after user successfully registered in the firebase. Try applying this code and check the firebase dashboard for authentication. And also Implement onFailureListener to know the reason why user is not being registered.
firAuth.createUserWithEmailAndPassword(_email, _pass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
mProgress.dismis();
if(task.isSuccessful()) {
//the user has been registered
Log.d("onSuccess","USER REGISTERED");
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
mProgress.dismis();
Log.e("onFailure",e.getMessage());
}
}
);
EDIT: If you are still facing the same issue go and check these settings in your firebase console authentication tab ,
Select SIGN-IN METHOD and Check the status of Email/Password if it is Disable then switch it to the Enable.
And it looks like you are using Genymotion, so have you installed the Google Libraries into your virtual device ?
If not follow this thread or test your app on a physical device
I am using Firebase's isEmailVerified method to verify an email. The following is the code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verifying);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
mAuth=FirebaseAuth.getInstance();
spinner=(ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.GONE);
Log.e("I am launched","hello");
if(user.isEmailVerified()==true){
Log.e("I am here","hello");
State state= new AccountSettingUp(this);
state.doAction();
} else {
Log.e("Maybe i am here","yes");
user.sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("email", "Email sent.");
}
}
});
}
Here, the else code should only run when the email is not verified. However, even after I verify the email and restart the activity, the if statement is not true and the email is sent again.
This behavior appears to be a limitation, possibly a bug, in the current version (10.0.1) of Firebase Authentication. The same issue is reported in this related question.
I tried doing a reload() of the user data after the email verification. That didn't help. As reported in the related question, it seems that a sign-out/sign-in is required to get the new email verification status.
For firebase-auth:10.0.1, it seems that it is not possible. However, the workaround is to log the user out and logging them in again. Upon signing in, the isEmailVerified() function will work properly.
I did a sign up activity
mAuth.createUserWithEmailAndPassword(Email, Password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
user = mAuth.getCurrentUser();
UserProfileChangeRequest profileChange = new UserProfileChangeRequest.Builder()
.setDisplayName(FirstName)
.build();
user.updateProfile(profileChange).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(getBaseContext(), "Thanks for signing up, " + FirstName + "! Please verify your email!", Toast.LENGTH_SHORT).show();
user.sendEmailVerification();
mAuth.signOut();
Intent a = new Intent(getBaseContext(),Login_Activity.class);
startActivity(a);
}
else {
Toast.makeText(getBaseContext(),"Failed to create username",Toast.LENGTH_SHORT).show();
}
}
});
}
else{
Toast.makeText(getBaseContext(),"Failed",Toast.LENGTH_SHORT).show();
}
}
});
As seen in the 'task.isSuccessful()' portion of the '.updateProfile' code, I did an 'mAuth.signOut();' and informing them to verify their email before sending them back to the login screen.
On the Login screen, I did a simple 'if (user.isEmailVerified())' statement to check for verification. If they are still not verified, a toast will appear to remind them, if they are verified then they will proceed into the next activity.
Hope this helps!
I want to check when a user attempts to signup with createUserWithEmailAndPassword() in Firebase user Authentication method, this user is already registered with my app.
To detect whether a user with that email address already exists, you can detect when the call to createUserWithEmailAndPassword () fails with auth/email-already-in-use. I see that #Srinivasan just posted an answer for this.
Alternatively, you can detect that an email address is already used by calling fetchSignInMethodsForEmail().
The usual flow for this is that you first ask the user to enter their email address, then call fetchSignInMethodsForEmail, and then move them to a screen that either asks for the rest of their registration details (if they're new), or show them the provider(s) with which they're signed up already.
When the user trying to create an user with same email address, the task response will be "Response: The email address is already in use by another account."
mFirebaseAuth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
//User registered successfully
}else{
Log.i("Response","Failed to create user:"+task.getException().getMessage());
}
}
});
First of all, you need to make sure you have that restriction enabled in Firebase console (Account and email address settings). Take a look at #Srinivasan's answer.
Then, do this in your java code:
firebaseAuthenticator.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
if (task.getException() instanceof FirebaseAuthUserCollisionException) {
Toast.makeText(SignUpActivity.this, "User with this email already exist.", Toast.LENGTH_SHORT).show();
}
} else {
sendVerificationEmail();
startActivity(new Intent(SignUpActivity.this, DetailsCaptureActivity.class));
}
// ...
}
});
This is where the trick happens:
if (task.getException() instanceof FirebaseAuthUserCollisionException) {
Toast.makeText(SignUpActivity.this,
"User with this email already exist.", Toast.LENGTH_SHORT).show();
Several exceptions can be thrown when registering a user with email and password, but the one we are interested in is the FirebaseAuthUserCollisionException. As the name implies, this exception is thrown if the email already exists. If the exception thrown is an instance of this class, let the user know.
As a practice of #Frank's answer here is the code of using fetchProvidersForEmail()
private boolean checkAccountEmailExistInFirebase(String email) {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
final boolean[] b = new boolean[1];
mAuth.fetchProvidersForEmail(email).addOnCompleteListener(new OnCompleteListener<ProviderQueryResult>() {
#Override
public void onComplete(#NonNull Task<ProviderQueryResult> task) {
b[0] = !task.getResult().getProviders().isEmpty();
}
});
return b[0];
}
I was looking into this kind of condition where we can detect if user exists or not and perform registration and login. fetchProvidersForEmail is best option right now. I have found this tutorial. Hope it helps you too!
See : Manage Users
UserRecord userRecord = FirebaseAuth.getInstance().getUserByEmail(email);
System.out.println("Successfully fetched user data: " + userRecord.getEmail());
This method returns a UserRecord object for the user corresponding to the email provided.
If the provided email does not belong to an existing user or the user cannot be fetched for any other reason, the Admin SDK throws an error. For a full list of error codes, including descriptions and resolution steps, see Admin Authentication API Errors.
private ProgressDialog progressDialog;
progressDialog.setMessage("Registering, please Wait...");
progressDialog.show();
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
//checking if success
if (task.isSuccessful()) {
//Registration was successfull:
Toast.makeText(RegistrationActivity.this, "Successfully registered!", Toast.LENGTH_LONG).show();
} else {
//Registration failed:
//task.getException().getMessage() makes the magic
Toast.makeText(RegistrationActivity.this, "Registration failed! " + "\n" + task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
progressDialog.dismiss();
}
});
Add below code to MainActivity.java file.When user attempt to register with the same email address a message "The email address is already used by another account" will pop up as a Toast
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()){
Toast.makeText(MainActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
if(task.isSuccessful()){
Toast.makeText(MainActivity.this, "Sign up successfull", Toast.LENGTH_SHORT).show();
}
}
});
You do not have to do anything because the backend of Firebase will do the job.
Unless you are referring to reauthenticating of the app.
Take a scenario for an example, w
I am trying to send a verification email after successful registration of user. Which gives me the error An internal error has occurred. [ USER_NOT_FOUND ]. This is the code I have at present -
public void signUpUser(View view){
EditText mailEditText = (EditText) findViewById(R.id.editText);
EditText pwdEditTet = (EditText) findViewById(R.id.editText2);
String email = mailEditText.getText().toString();
String password = pwdEditTet.getText().toString();
Log.d("Info",email);
Log.d("Info",password);
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
try {
AuthResult result = task.getResult();
Log.d("Sign up", "createUserWithEmail: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()) {
Toast.makeText(MainActivity.this, R.string.auth_failed,
Toast.LENGTH_SHORT).show();
}else{
Log.d("Sign up", "Sending verification email");
// Sending the verification email
//FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
mAuth.getCurrentUser().sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("Email Sent", "Verification Email sent.");
}else{
Log.d("Email Sent",task.getException().getLocalizedMessage());
}
}
});
}
} catch (Exception e){
Toast.makeText(MainActivity.this,R.string.user_exist,Toast.LENGTH_SHORT).show();
Log.e("Exception",e.getLocalizedMessage());
}
}
});
}
and here is the log which is getting printed -
10-11 10:10:50.372 31518-31518/au.com.savedme D/Sign up: Sending verification email
10-11 10:10:51.438 31518-31518/au.com.savedme D/Email Sent: An internal error has occurred. [ USER_NOT_FOUND ]
10-11 10:11:00.429 31518-31538/au.com.savedme W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
Please have a look and let me know in case I am doing anything wrong here.
I also had the same issue, and the reason i found behind this is, if you are trying this code with same user which you have already created and then deleted it from firebase console, it will not work.
Try with new email address which you have not tried a single time, and it will work.
Note that createUserWithEmailAndPassword() not only creates the user,
but also, if successful, signs the user in. When the creation and
sign-in occurs when there is an existing signed-in user, there appears
to be a Firebase bug related to signing out and clearing the cache for
the previous user.
I was able to make your code work for a previously signed-in and later
deleted user by calling signOut() before
createUserWithEmailAndPassword().
reference
I am having the same problem. What I found out is that, mAuth.getCurrentUser().sendEmailVerification() is not working inside mAuth.createUserWithEmailAndPassword(email,password) method.
I wrote the code outside the createUserWithEmailAndPassword(email,password) method and bang I received the verification email. Strange.
FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
if(user!=null){
user.sendEmailVerification().addOnCompleteListener(MainActivity.this,new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Log.i("Success","Yes");
}
else {
Log.i("Success","No"+task.getException());
}
}
});
}
Are you sure you have enabled Email/Password authentication in console? If not, you can go to https://console.firebase.google.com and click on your project, click 'Auth', then 'SIGN-IN METHOD', click on pen icon to enable it. Hope this helps!
I'm trying to code a Delete User method in my Android App, but I have some issues each time I execute it. This method will be executed when a user pushes the Delete account button on an Activity. My apps works with FirebaseUI Auth.
Here is the method:
private void deleteAccount() {
Log.d(TAG, "ingreso a deleteAccount");
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
final FirebaseUser currentUser = firebaseAuth.getCurrentUser();
currentUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG,"OK! Works fine!");
startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
finish();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG,"Ocurrio un error durante la eliminación del usuario", e);
}
});
}
1) When I execute that function a Smart Lock message appears on the screen and the user is signed in again. Here is a screenshot of this message.
2) On other occasions, when the user is logged in for a long time, the function throws an Exception like this:
06-30 00:01:26.672 11152-11152/com.devpicon.android.firebasesamples E/Main3WelcomeActivity: Ocurrio un error durante la eliminación del usuario
com.google.firebase.FirebaseException: An internal error has occured. [ CREDENTIAL_TOO_OLD_LOGIN_AGAIN ]
at com.google.android.gms.internal.zzacq.zzbN(Unknown Source)
at com.google.android.gms.internal.zzacn$zzg.zza(Unknown Source)
at com.google.android.gms.internal.zzacy.zzbO(Unknown Source)
at com.google.android.gms.internal.zzacy$zza.onFailure(Unknown Source)
at com.google.android.gms.internal.zzact$zza.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:453)
I've read that I have to re-authenticate the user but I'm not sure how to do this when I'm working with Google Sign In.
As per the Firebase documentation can user delete() method to remove user from the Firebase
Before remove the user please reAuthenticate the user.
Sample code
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User account deleted.");
}
}
});
}
});
For more details : https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user
If you want to user re Authentication with other singin provider only need to change the Provider for GoogleAuthProvider below is the sample code
GoogleAuthProvider.getCredential(googleIdToken,null);
The answer provided by Ansuita Jr. is very beautifully explained and is correct with just a small problem.
The user gets deleted even without having successful re-authentication.
This is because we use
user.delete()
in the onComplete() method which is always executed.
Therefore, we need to add an if check to check whether the task is successful or not which is mentioned below
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.e("TAG", "onComplete: authentication complete");
user.delete()
.addOnCompleteListener (new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.e("TAG", "User account deleted.");
} else {
Log.e("TAG", "User account deletion unsucessful.");
}
}
});
} else {
Toast.makeText(UserProfileActivity.this, "Authentication failed",
Toast.LENGTH_SHORT).show();
}
}
});
Your delete callback already handles the case of a failure, why do you add addOnFailureListener later?
Try to delete it, this way:
private void deleteAccount() {
Log.d(TAG, "ingreso a deleteAccount");
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
final FirebaseUser currentUser = firebaseAuth.getCurrentUser();
currentUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG,"OK! Works fine!");
startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
finish();
} else {
Log.w(TAG,"Something is wrong!");
}
}
});
}
First of all, you need to store the auth token or the password at the moment your user is logging in. If your app doesn't provide such as Google Sign-in, Facebook Sign-in or others, you just need to store the password.
//If there's any, delete all stored content from this user on Real Time Database.
yourDatabaseReferenceNode.removeValue();
//Getting the user instance.
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
//You need to get here the token you saved at logging-in time.
String token = "userSavedToken";
//You need to get here the password you saved at logging-in time.
String password = "userSavedPassword";
AuthCredential credential;
//This means you didn't have the token because user used like Facebook Sign-in method.
if (token == null) {
credential = EmailAuthProvider.getCredential(user.getEmail(), password);
} else {
//Doesn't matter if it was Facebook Sign-in or others. It will always work using GoogleAuthProvider for whatever the provider.
credential = GoogleAuthProvider.getCredential(token, null);
}
//We have to reauthenticate user because we don't know how long
//it was the sign-in. Calling reauthenticate, will update the
//user login and prevent FirebaseException (CREDENTIAL_TOO_OLD_LOGIN_AGAIN) on user.delete()
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
//Calling delete to remove the user and wait for a result.
user.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//Ok, user remove
} else {
//Handle the exception
task.getException();
}
}
});
}
});
}
#Android developers:
I faced an issue where the Firebase Auth information was persisting in the device's disk AFTER uninstalling the app. After experimenting and reading about it, I found that setting android:allowBackup="false" and android:fullBackupContent="false" in the Manifest's <application> tag will ensure the identity information is not persisted after the app is uninstalled.
Please note, this kind of persistence was not happening on all Android devices. In fact, it started happening on one of my devices that never had this issue.
If the sign-in method is "Anonymous", you can just call
FirebaseAuth.getInstance().getCurrentUser().delete().addOnCompleteListener(task -> {
if (task.isSuccessful()){
Log.d(TAG, "Deletion Success");
}
});
But if it's a different method, you will need a re-authentication.
How to re-authenticate
Use this methods :-
remove()
is equivalent to calling set(null).
or
removeUser()
removeUser(credentials, [onComplete])
Only get current user and delete it by using following method it'll work fine
user.delete();
and you can add on Oncompletelistner also
by addinduser.delete().addOnCompleteListner(new OnCompleteListner)and more on
If you are using AuthUI or FirebaseAuth you can just do the following
AuthUI.getInstance().delete(context).addOnSuccessListener {
}.addOnFailureListener{
}
OR
FirebaseAuth.getInstance().currentUser.delete().addOnSuccessListener...
If you are using FirebaseUI Auth you can just do the following
private void delete() {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseUser user=firebaseAuth.getCurrentUser();
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
finish();
Toast.makeText(Main3WelcomeActivity.this,"Account deleted",Toast.LENGTH_LONG).show();
}else {
Toast.makeText(Home.this,"failed",Toast.LENGTH_LONG).show();
}
}
});}