How to send Firebase email confirmation on signup? - android

So, I have enabled email/password in the dev console and everything is working fine. Except that I should be getting a confirmation email to the email I inputted, but I'm not getting it. I thought it does it automatically, but apparently it doesn't.
Method for signup:
public void signUp(View v) {
String email = emailET.getText().toString();
String password = passwordET.getText().toString();
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d("AD", "createUserWithEmail: " + task.isSuccessful() + task.getException());
if (!task.isSuccessful()) {
createDialogSignUpError(
getApplicationContext().getResources().getString(R.string.signUpFailedET),
getApplicationContext().getResources().getString(R.string.signUpFailedEM),
getApplicationContext().getResources().getString(android.R.string.ok));
Toast.makeText(SignUp.this, task.getException().toString(), Toast.LENGTH_LONG).show();
} else if (task.isSuccessful()) {
Toast.makeText(SignUp.this, "Registration Successful.", Toast.LENGTH_SHORT).show();
}
}
});
}
It should be sending, but sadly it's not. I've read somewhere on SO that you need to add a method or something to send the email, and it's missing in the docs, but that wasn't Java.
Edit
According to here, it is only supported in iOS and web. Which is pretty surprising, since after all, android IS Google, and Google is Firebase. So is it possible even with creating a custom sent email?
Edit 2: To be more clear, does Android have an Email sender like C#. That would be the best solution if there isn't an API for this.

Now according to the updated firebase documentation
Here is how to send a verification mail to the user that in your case is after creating the account and letting the user to log-in then send him/her a notification that he have to verify the account and then the next login is blocked until he/she didn't verify (I think this is better than making the user is forced to open his email first)
Send a user a verification email
You can send an address verification email to a user with the
sendEmailVerification method. For example:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Email sent.");
}
}
});

You can now plug any Firebase gaps in email coverage by rolling your own email sender using Firebase Cloud Functions. There's an example here. Of course this means more work than just configuring like the built-in options but at least means we can do whatever we need to do. :)

Related

Firebase email verification WITHOUT creating and account

I'm creating an Android application that will deliver notifications.
Users can opt-in with a phone number or an email account.
I just need to verify the email the user entered, I don't want to create a Firebase account
Firebase has a FirebaseUser#sendEmailVerification() but that will require to create an account.
In other words, I just want the email verification to be the same as the Phone verification, where Firebase will just send you a code or verification link.
Is there a way to leverage Firebase email verification without creating an account?
For anyone trying to accomplish the same, here's how I was able to do it.
Go to Fibrebase console and enable Email/Password and Anonymous sign-in methods on the Authentication screen
Firebase Authentication screen
Then in you code, create an Anonymous user (this is what does the trick, because now you have a valid user to verify against), change the email, and then send a verification. After that, reload the Firebase user and check isEmailVerified()
mAuth = FirebaseAuth.getInstance();
mAuth.signInAnonymously()
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "signInAnonymously:success");
if (mAuth.getCurrentUser().isEmailVerified() == false) {
mAuth.getCurrentUser().updateEmail("<MAIL YOU WANTO TO VERIFY HERE>");
mAuth.getCurrentUser().sendEmailVerification();
Log.e(TAG, "mail sent.....................................");
}
//updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInAnonymously:failure", task.getException());
Toast.makeText(getApplicationContext(), "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
}
});
Here's the reloading part:
mAuth.getCurrentUser().reload()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.e(TAG,( mAuth.getCurrentUser().isEmailVerified() ? "VERIFIED" : "Not verified"));
}
});
Both phone number verification and email verification are tied to a Firebase Authentication account. There is no way to use them with such an account, since the result of a verification is that a the relevant property (email_verified or phone_number) in the user account gets updated.

Signup Firebase user without e-mail address

I'm using the following steps to sign-up a new Firebase user. Is there a way for me to set a username parameter so in the future the user can login using a username & password ?
Also, is there a way to sign up only using a username & password ,ie, I would not like to have an option of e-mail ID.
I've gone through the following solution, but it doesn't seem efficient. I suppose there is a better way of doing so.
Firebase login and signup with username
private FirebaseAuth auth;
//Get Firebase auth instance
auth = FirebaseAuth.getInstance();
//create user
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignupActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toast.makeText(SignupActivity.this, "createUserWithEmail:onComplete:" + task.isSuccessful(), Toast.LENGTH_SHORT).show();
// 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(SignupActivity.this, "Authentication failed." + task.getException(),
Toast.LENGTH_SHORT).show();
} else {
startActivity(new Intent(SignupActivity.this, MainActivity.class));
finish();
}
}
});
You can add any domain behind the username
register your user with < username > #summersApp.com.
Note that this will make it impossible to for the user to reset their password if they forget it, since Firebase uses the email address to send the password reset email.
To answer OP's question in comments above,
To save extra information to a user, link a reference in the database to their UID as shown here
Example:
/users
/uid1
no.of.posts: 3,
no.of.friends: 4
/uid2
no.of.posts: 5,
no.of.friends: 6
/uid3
no.of.posts: 7,
no.of.friends: 8

Change password with Firebase for Android

I want to implement change password functionality for my application.
I included com.google.firebase:firebase-auth:9.0.2 in my build.gradle file and so far everything has been working fine until I tried to implement change password functionality.
I found that the FirebaseUser object has a updatePassword method that takes a new password as the parameter. I could use this method and implement validation myself. However, I need the user's current password for comparing with the inputted one and I can't find a way to get that password.
I also found another method on the Firebase object that takes the old password, new password, and a handler. The problem is that I need to also include com.firebase:firebase-client-android:2.5.2+ to access this class and when I am trying this method I'm getting to following error:
Projects created at console.firebase.google.com must use the new Firebase Authentication SDKs available from firebase.google.com/docs/auth/
Feel like I'm missing something here. What's the recommended approach for implementing this? And when to use what dependency?
I found a handy example of this in the Firebase docs:
Some security-sensitive actions—such as deleting an account, setting a
primary email address, and changing a password—require that the user
has recently signed in. If you perform one of these actions, and the
user signed in too long ago, the action fails and throws
FirebaseAuthRecentLoginRequiredException. When this happens,
re-authenticate the user by getting new sign-in credentials from the
user and passing the credentials to reauthenticate. For example:
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) {
if (task.isSuccessful()) {
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Password updated");
} else {
Log.d(TAG, "Error password not updated")
}
}
});
} else {
Log.d(TAG, "Error auth failed")
}
}
});
Changing password in firebase is bit tricky. it's not like what we usually do for changing password in server side scripting and database. to implement change password functionality in your app, first you need to get the user's email from FirebaseAuth or prompt user to input email and after that prompt the user to input old password because you can't retrieve user's password as Frank van Puffelen said. After that you need to reauthenticate that. Once reauthentication is done, if successful, you can use updatePassword(). I have added a sample below that i used for my own app. Hope, it will help you.
private FirebaseUser user;
user = FirebaseAuth.getInstance().getCurrentUser();
final String email = user.getEmail();
AuthCredential credential = EmailAuthProvider.getCredential(email,oldpass);
user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
user.updatePassword(newPass).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(!task.isSuccessful()){
Snackbar snackbar_fail = Snackbar
.make(coordinatorLayout, "Something went wrong. Please try again later", Snackbar.LENGTH_LONG);
snackbar_fail.show();
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Password Successfully Modified", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}else {
Snackbar snackbar_su = Snackbar
.make(coordinatorLayout, "Authentication Failed", Snackbar.LENGTH_LONG);
snackbar_su.show();
}
}
});
}
}
There is no way to retrieve the current password of a user from Firebase Authentication.
One way to allow your users to change their password is to show a dialog where they enter their current password and the new password they'd like. You then sign in (or re-authenticate) the user with the current passwordand call updatePassword() to update it.
I googled something about resetting Firebase passwords and got to this page. It was helpful but didn't get me all the way to the finish line: I still had to Google around for five or ten minutes. So I'm back to improve the answer for VueJS users.
I see lots of code here using "FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();" in the top line. That's a piece of the puzzle mentioned in the most popular two answers.
But I couldn't get that to work in my project, which is written in VueJS. So I had to go exploring.
What I found was another page of the Firebase documentation. It's the same page people are getting the quoted code from (I think), but with the documentation written for Web instead of Android/Java.
So check out the first link if you're here using VueJS. I think it'll be helpful. "Get the currently signed-in user" might contain the appropriate code for your project. The code I found there says:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
That page I linked up above ("another page") brought me eventually to the "Set a user's password" part of the Web docs. Posters here correctly state that the user must have been authenticated recently to initiate a password update. Try this link for more on re-authenticating users.
"Set a user's password":
// You can set a user's password with the updatePassword method. For example:
var user = firebase.auth().currentUser;
var newPassword = getASecureRandomPassword();
user.updatePassword(newPassword).then(function() {
// Update successful.
}).catch(function(error) {
// An error happened.
});
"Re-authenticate a user"
var user = firebase.auth().currentUser;
var credential;
// Prompt the user to re-provide their sign-in credentials
user.reauthenticateWithCredential(credential).then(function() {
// User re-authenticated.
}).catch(function(error) {
// An error happened.
});
Query revolves around users forgetting their passwords or wishing to reset their passwords via an email letter. Which can be attained by Auth.sendPasswordResetEmail("email#gmail.com");
begin by initializing
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String DummyEmail = "Dummy#gmail.com"
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
}
}
};
Somewhere else when a user requests to update or reset their passwords simply access the mAuth,
private void PassResetViaEmail(){
if(mAuth != null) {
Log.w(" if Email authenticated", "Recovery Email has been sent to " + DummyEmail);
mAuth.sendPasswordResetEmail(DummyEmail);
} else {
Log.w(" error ", " bad entry ");
}
}
Now, needless to burden yourself querying around your database to find whether the Email exits or not, Firebase mAuth will handle that for you.
Is the Email authenticated? Is it active in your Authentication list? Then send a password-reset Email.
The content will look something like this
the reset link will prompt the following dialog on a new web page
Extra
if you're bit nerved by the reset-template "devised" by Firebase. You can easily access and customize your own letter from the Firebase Console.
Authentication > Email templates > Password reset
A simple approach to handle changing a password is to send a password reset email to the user.
FirebaseAuth.getInstance().sendPasswordResetEmail("user#example.org")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(Activity.this, "Password Reset Email Sent!"), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(Activity.this, task.getException().getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
This is a kotlin solution to the problem I am putting the method here Hope it helps
// The method takes current users email (currentUserEmail), current users old password (oldUserPassword), new users password (newUserPassword) as parameter and change the user password to newUserPassword
private fun fireBasePasswordChange(
currentUserEmail: String,
oldUserPassword: String,
newUserPassword: String
) {
// To re authenticate the user credentials getting current sign in credentials
val credential: AuthCredential =
EmailAuthProvider.getCredential(currentUserEmail, oldUserPassword)
// creating current users instance
val user: FirebaseUser? = FirebaseAuth.getInstance().currentUser
// creating after successfully re authenticating update password will be called else it will provide a toast about the error ( makeToast is a user defined function here for providing a toast to the user)
user?.reauthenticate(credential)?.addOnCompleteListener { task ->
when {
task.isSuccessful -> {
user.updatePassword(newUserPassword).addOnCompleteListener {
if (it.isSuccessful) {
makeToast("Password updated")
// This part is optional
// it is signing out the user from the current status once changing password is successful
// it is changing the activity and going to the sign in page while clearing the backstack so the user cant come to the current state by back pressing
FirebaseAuth.getInstance().signOut()
val i = Intent(activity, SignInActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i)
(activity as Activity?)!!.overridePendingTransition(0, 0)
} else
makeToast("Error password not updated")
}
}
else -> {
makeToast("Incorrect old password")
}
}
}
}

Firebase - how to update another user's email?

I see in the docs how to update your own email once you are logged in, like so:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.updateEmail("user#example.com")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "User email address updated.");
}
}
});
What I want, though, is to be logged in as an user and be able to update the email of another user(The logged in user is an admin). With the approach above that's not possible, because you can get only the current user from FirebaseAuth.
Does anyone know how to achieve that?
There is currently no administrative API for Firebase Authentication. We're working on adding this to our server SDKs, but there is no definitive timeline for its availability yet.

Email verification using Firebase 3.0 on Android

I knew that we can verify the users email with Firebase Auth 3.0. I'm not able to find any documentation regarding email verification on Android. I'm able to find the same for iOS as well as web but not for Android. Any link to the documentation would be helpful.
From the image, it is clear that once the user signs in, he will be intimated regarding that on email to confirm his subscription. I've subscribed myself and also verified in the users section in Auth tab and I am able to see my mail id and firebase generated unique user id. What's missing here is the confirmation email to my email id. Did some one try this or am I too early trying this? Thanks for your help.
Email verification for android is now available in Firebase.
See this release note:
https://firebase.google.com/support/release-notes/android#9.6
Update
Email verification is available in version 9.6 and higher of the Firebase SDK for Android.
Original answer
Email verification is not available for Android yet. Also answered here with more context.
An alternative suggested by the Firebase team
One thing you could do is to add a node to your Firebase Database which contains all email addresses as children. You should make this node only publicly readable (via Firebase security rules).
Then from within your apps, once a user signs up / signs in, you check if the email of that user is on the list, and if not, you sign them out and kick them out of your app (and as a bonus, you could even log the intruder's email address in your database, so you can later check who is trying to access your app).
This will work for initial testing if you know the e-mail ids of the people who are gonna test your app until the e-mail verification makes its way to Android.
Since email verification only works with Email/Password authentication, the best place to send it wold be in the onComplete method of createUserWithEmailAndPassword(...) method, after signup is successful.
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
sendVerificationEmail();
....
The custom sendVerification method is:
public void sendVerificationEmail() {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
user.sendEmailVerification()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(SignUpActivity.this, "Signup successful.
Verification email sent", Toast.LENGTH_SHORT).show();
}
}
});
}
}
You can then check if the user has verified their email anywhere in your app by calling:
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
firebaseUser = firebaseAuth.getCurrentUser();
if (firebaseUser != null ) {
Log.e(TAG, firebaseUser.isEmailVerified() ? "User is signed in and email is verified" : "Email is not verified");
} else {
Log.e(TAG, "onAuthStateChanged:signed_out");
}
}
};

Categories

Resources