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
Related
I am trying to be able to register users into my database.
After I register the users they are being added to my firebase authentication which is great but nothing is changed in my Realtime Database.
It's worth mentioning that my Firebase location isn't in the US.
I have tried many different things:
Put the firebase link inide of the "getInstance()"
Replace the current google-services file with an updated one, including the Firebase's link inside of it
use getReferenceFromUrl() with the firebase's link inside of it.
None of those seemed to work.
Main part of the code in which I'm trying to register the user:
mAuth.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()){
User user = new User(name, email, password);
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(RegisterUser.this, "User Registered", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(RegisterUser.this, "Failed to register user", Toast.LENGTH_SHORT).show();
}
}
});
}else{
Toast.makeText(RegisterUser.this, "Failed to register user", Toast.LENGTH_SHORT).show();
}
}
});
These are the Realtime Database rules:
{
"rules": {
".read": "true",
".write": "true"
}
}
It's worth noting that I have tried everything I found, including an answer to the same question in this site. Unfortunately none seem to work for me so I had to ask to understand the issue.
Thanks.
When i am creating new account its name equals users UID is there anyway to change it to custom name?
My code
mAuth.createUserWithEmailAndPassword(Email, Password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
User user = new User(Name, LastName, Email);
curentUser = Name + " " + LastName;
FirebaseDatabase.getInstance().getReference("No server")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(MainActivity.this, "User has been registered successfully!", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MainActivity.this,"Failed to register! try again!", Toast.LENGTH_LONG).show();
}
}
});
}else{
Toast.makeText(MainActivity.this,"Failed to register! try again!", Toast.LENGTH_LONG).show();
}
}
});
How it looks like
You can't change the key of an existing value in Firebase Realtime Database without reading the value, write it under a new key, and delete the old one.
That being said, you chose the key of the user object yourself:
FirebaseDatabase
.getInstance().getReference()
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user)
The child method contains the key for the value you set in setValue. And you use the current user's UID for this.
You can change this to whatever value you like. For example, you could the user's email as a key (see reference for current user object):
.child(FirebaseAuth.getInstance().getCurrentUser().getEmail())
Note: See the comment from #puf below, you might want to encode an email address when using as a key.
I have the following in a login activity that gets triggered to sign in a user to my app:
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
...
LoggedInUser loggedInUser = LoggedInUser.getInstance();
Toast.makeText(LoginActivity.this, getString(R.string.welcome_back) + loggedInUser.getUser().name, Toast.LENGTH_LONG).show();
The sign in and the listener above are successfully triggered. However, I am having an issue occur on that Toast line where I call loggedInUser.getUser().name
public User getUser() {
if (user == null) {
FirebaseAuth mAuth = FirebaseAuth.getInstance();
String userID = mAuth.getCurrentUser().getUid();
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users").child(userID);
databaseReference.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (!task.isSuccessful()) {
Log.e("firebase", "Error getting data", task.getException());
}
else {
User currUser = task.getResult().getValue(User.class);
user = currUser;
}
}
});
}
return user;
}
What happens here is that databaseReference.get().addOnCompleteListener never gets triggered so user is never set, it returns null and the app crashes.
I utilized the same code I have in getUser to set a user elsewhere with no issues so I am not sure what I am missing here that is causing the listener to be skipped. I am new to firebase so any help to understand and fix this is appreciated!
Not sure if I fully understand your code but you can get your user object from mAuth.getCurrentUser() inside signInWithEmailAndPassword.
Refer to the docs.
Also bear in mind that calls to the Firebase database are asynchronous. So this means in your getUser() method, you'll probably get a null return when you enter the if == null block i.e your addOnCompleteListener executes after your return user statement.
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 am creating an android app that registers a user to firebase Authentication. So as you can see below this is the program i made to give you a hint on what i am referring . . .
public void createAccount(final String email, final String password, final String firstname, final String lastname)
{
mAuth.createUserWithEmailAndPassword(email, password)
.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, "createUserWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
UserInformation UInfo = new UserInformation(user.getUid(), user.getEmail(), password, firstname, lastname);
newRef = database.getReference("Users");
newRef.child(user.getUid()).setValue(UInfo);
//newRef.child(user.getUid()).child("id").setValue(user.getUid());
Toast.makeText(Signup.this, "User registered: " + user.getEmail(), Toast.LENGTH_LONG).show();
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(Signup.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
}
after register succeeds all other devices also gets affected as well, in terms of, all the other devices prompts as if they've just logged in again.
my problem is, why does it do that? why does all other devices gets affected as if they've just logged in again. what's causing the issue?
also, this is my database rules.
{
"rules": {
".read": true,
".write": true
}
}