I have a problem here. I want to know whether the user has verified the email or not. If the user has verified the email by clicking on the link given, the application should automatically go to the homeScreen. Or else, the user may remain on the same page.
Below is a part of my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_email_verification);
emailVerify = findViewById(R.id.emailVerify);
final FirebaseUser user = auth.getCurrentUser();
Intent intent = getIntent();
name = intent.getStringExtra("name");
email = intent.getStringExtra("email");
password = intent.getStringExtra("password");
emailVerify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
user.sendEmailVerification().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
storeNewUsersData();
Toast.makeText(v.getContext(), "Verification email has been sent.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: Email not sent " + e.getMessage());
}
});
//check whether the user has verified the email and go to homeScreen
}
});
}
Try this:
public void verifyEmail() {
if (firebaseAuth.getCurrentUser().isEmailVerified()) { //FirbaseUser must not be null!
Toast.makeText(view.getContext(), "Email has been verified.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(view.getContext(), "Email has not been verified.", Toast.LENGTH_SHORT).show();
}
}
https://www.youtube.com/watch?v=Wf7DDIaRYjk This tutorial maybe helpful I implemented mine from this.
Related
Want to update profile, started with email to get the hang off. Whenever I click on it to update the email, it adds a new UID for that email alone instead of adding it to the user profile with that UID. Really stuck now. I did have it working but cant seem to get back to it so must be an error here somewhere, thanks,
updateProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String updateEmail = emailTextView.getText().toString();
user.updateEmail(updateEmail).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
firebaseDatabase.getReference("Users").child(user.getUid()).child("email").setValue(updateEmail);
Toast.makeText(getApplicationContext(), "Email update", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
}
UPDATE
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
final String uid = firebaseUser.getUid();
Log.d(TAG, "USERID="+uid);
Doin this got me a UID from a completely different user! It did let me change the email for them when I did this but thats no use. Having similar issues deleting users. Is it an issue with a UID does it create a new one everytime they log in?
In my app, First, I am verifying phone numbers by using phone authentication of firebase.
I am doing this process in the OTPVerificationActivity class. Every thing is working fine in this class, I am getting the OTP code also and the user gets signed in.
If the phone number is verified, then I am verifying the email by sending the verification email. I am doing this process in the EmailVerificationActivity class. In this class first, i am checking is the user exists or not. if the user is there, then I am logging out the user.
Then i create the account using createUserWithEmailAndPassword function. After this, i want to send a verification email to the user.
PROBLEM:- Now the problem is, after creating the account,onCreate method gets called again. Due to this, I am unable to send the verification email and the further task. So how to stop onCreate method from getting called again.
NOTE :-
I tried to run only EmailVerificationActivity not OTPVerificationActivity.
In that case every thing was working properly. I was able to send verification email and also able to verify the user.
But when i am using the OTPVerificationActivityand EmailVerificationActivity together i am getting this problem.
So please help me to solve this problem.
public class OTPVerificationActivity extends AppCompatActivity {
String verificationID;
TextView messageTV;
EditText OTPET;
FirebaseAuth mAuth;
FirebaseAuth.AuthStateListener mAuthStateListener;
PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallBack = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
signInWithCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
}
#Override
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
verificationID = s;
Log.i("onSend",s);
}
};
String phoneNumber;
public void sendVerificationCode(View view)
{
String code = OTPET.getText().toString();
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationID,code);
signInWithCredential(credential);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_otpverification);
messageTV = (TextView) findViewById(R.id.messageTextView);
OTPET = (EditText) findViewById(R.id.OTPEditText);
mAuth = FirebaseAuth.getInstance();
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if(firebaseAuth.getCurrentUser() != null)
{
firebaseAuth.signOut();
if(firebaseAuth.getCurrentUser() == null)
{
Intent intent = new Intent(OTPVerificationActivity.this,EmailVerification.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
else
{
Log.i("firebaseAuth","user is not null");
}
}
}
};
String message = "Please type the verification code sent to ";
messageTV.setText(message+" " + "+91 " + getIntent().getStringExtra("phoneNumber"));
phoneNumber = "+91" + getIntent().getStringExtra("phoneNumber");
sendPhoneNumber(phoneNumber);
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthStateListener);
}
#Override
protected void onDestroy() {
super.onDestroy();
if(mAuth.getCurrentUser() != null)
{
mAuth.signOut();
}
}
public void sendPhoneNumber(String number)
{
Log.i("sendPhoneNumber","inside it");
PhoneAuthProvider.getInstance().verifyPhoneNumber(
number,
60,
TimeUnit.SECONDS,
TaskExecutors.MAIN_THREAD,
mCallBack
);
Log.i("sendPhoneNumber","outside it");
}
private void signInWithCredential(final PhoneAuthCredential credential)
{
mAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful())
{
Toast.makeText(OTPVerificationActivity.this, "Sign in Failed.", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(OTPVerificationActivity.this, "Phone number verified.", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.i("FailedListener",e.getMessage());
}
});
}
}
Below is the code of EmailVerificationActivity class.
public class EmailVerification extends AppCompatActivity {
EditText emailET, passwordET, confirmPasswordET;
AlertDialog.Builder builder;
AlertDialog alertDialog;
ProgressDialog progressDialog;
FirebaseAuth mAuth;
FirebaseAuth.AuthStateListener mAuthStateListener;
public void login(View view)
{
startActivity(new Intent(EmailVerification.this,MainActivity.class));
}
public void submit(View view)
{
String email = emailET.getText().toString();
String password = passwordET.getText().toString();
String confirmPassword = confirmPasswordET.getText().toString();
if(!(TextUtils.isEmpty(email) && TextUtils.isEmpty(password)))
{
if(password.equals(confirmPassword))
{
progressDialog.show();
mAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful())
{
//acount created...
mAuth.getCurrentUser().sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.i("verificationEmail","send");
progressDialog.dismiss();
if(!EmailVerification.this.isFinishing())
{
alertDialog.show();
}
Toast.makeText(EmailVerification.this, "Email send successfully.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.i("verificationEmail","Not send");
//failed to create account...
progressDialog.dismiss();
Toast.makeText(EmailVerification.this, "Failed to create account", Toast.LENGTH_SHORT).show();
}
});
}
else
{
//account not created...
progressDialog.dismiss();
Log.i("taskNotSuccessful",task.getException().getMessage());
Toast.makeText(EmailVerification.this, "Problem in creating account", Toast.LENGTH_SHORT).show();
}
}
});
}
else
{
Toast.makeText(this, "Confirm Password is not same as Password.", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "Fields are empty.", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_email_verification);
Log.i("onCreate","inside it");
initializeWidgets();
progressDialog = new ProgressDialog(EmailVerification.this);
progressDialog.setMessage("Sending verification email.");
builder= new AlertDialog.Builder(EmailVerification.this);
builder.setTitle("Email Verification")
.setMessage("We sent you a verification email, Please verify email before moving further.")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(EmailVerification.this,SignInActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
});
alertDialog = builder.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(R.style.MyProgressDialogStyle);
}
});
mAuth = FirebaseAuth.getInstance();
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if(firebaseAuth.getCurrentUser() != null)
{
// user is signed up...
Log.i("mAuthStateChanged","user is not null.");
}
else
{
Log.i("mAuthStateChanged","user is null");
}
}
};
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthStateListener);
}
private void initializeWidgets()
{
emailET = (EditText) findViewById(R.id.EmailEditText);
passwordET = (EditText) findViewById(R.id.PasswordEditText);
confirmPasswordET = (EditText) findViewById(R.id.ConfirmPasswordEditText);
}
}
This is the android life cycle. onCreate() will be called again, if your activity was destroyed due to release memory, explicitly killing and etc.
When you switch activities usually activities won't get killed. but it may be killed in some cases. so please move your codes from onCreate() to somewhere else.
You can not control android life cycle. It will happen anyway. therefore you need to obey them
I have a pretty simple challenge here USING firebase Auth by email. I
first check if the email exists which is working well. but the program
gives me a toast of "Please enter email..." Check me code
below.
Should proceed next if the email does not exist. when email does not
exist. my (TextUtils.isEmpty(email)) toast to me to enter the
email.
public class RegistreActivity extends AppCompatActivity {
EditText e4;
FirebaseAuth auth;
String email;
ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registre);
e4 =(EditText)findViewById(R.id.temail);
auth= FirebaseAuth.getInstance();
}
public void goToPasswordActivity(View v){
auth.fetchSignInMethodsForEmail(e4.getText().toString())
.addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
#Override
public void onComplete(#NonNull Task<SignInMethodQueryResult> task) {
if (task.isSuccessful()){
boolean check =!task.getResult().getSignInMethods().isEmpty();
if (!check){
Intent intent = new Intent(RegistreActivity.this,PasswordActivity.class);
intent.putExtra("email",e4.getText().toString());
startActivity(intent);
}
else {
Toast.makeText(getApplicationContext(),"email alredy exst",Toast.LENGTH_LONG).show();
}
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "Please enter email...", Toast.LENGTH_LONG).show();
return;
}
}
}
});
}
}
You never seem to be giving email a value anywhere, which explains why if (TextUtils.isEmpty(email)) executes the block of code that shows the toast you don't want.
I suspect that you want email to be the value the user entered into e4.getText().toString(). If that's the case, I'd recommend doing that before the call to auth.fetchSignInMethodsForEmail, and also to check whether the user entered a value there, instead of after the call to Firebase.
So something like:
String email = e4.getText().toString();
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "Please enter email...", Toast.LENGTH_LONG).show();
}
else {
auth.fetchSignInMethodsForEmail(email)
.addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
#Override
public void onComplete(#NonNull Task<SignInMethodQueryResult> task) {
if (task.isSuccessful()){
boolean check =!task.getResult().getSignInMethods().isEmpty();
if (!check){
Intent intent = new Intent(RegistreActivity.this,PasswordActivity.class);
intent.putExtra("email", email);
startActivity(intent);
}
else {
Toast.makeText(getApplicationContext(),"email already exst",Toast.LENGTH_LONG).show();
}
}
}
});
}
}
I want to give the user in my app the possibility to delete his account so when he clicks on the delete button a document gets deleted which contains all his informations. The name of the document is his displayName so I get this as a string but when I run the code you are seeing below I get a NullpointerException in this line:
String currentUsername = user.getDisplayName();
even though the displayName is not null.
Edit:
I found the solution on my own, see the answer below.
Here is my method:
btn_delete_account.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
deleteDocument();
}
}
});
}
});
...
public void deleteDocument (){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String currentUsername = user.getDisplayName();
db.collection("User").document(currentUsername)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
Toast.makeText(PersonalSettings.this, "Your account was successfully deleted.", Toast.LENGTH_SHORT).show();
Intent i = new Intent(PersonalSettings.this, SignInActivity.class);
startActivity(i);
finish();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
First thing you have to check that current user is not null
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user==null)
{
return;
}
if current user is not null then get its name and further check that it's name is not null.
String currentUsername = user.getDisplayName();
if(TextUtils.isEmpty(currentUsername))
{
return;
}
if name is not null then go for delete document as follows :
public void deleteDocument (){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user==null)
{
return;
}
String currentUsername = user.getDisplayName();
if(TextUtils.isEmpty(currentUsername))
{
return;
}
db.collection("User").document(currentUsername)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
Toast.makeText(PersonalSettings.this, "Dein Account wurde erfolgreich gelöscht.", Toast.LENGTH_SHORT).show();
Intent i = new Intent(PersonalSettings.this, SignInActivity.class);
startActivity(i);
finish();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
I think you're misunderstanding the error. It's saying that user is null, not the display name. This means there is currently no user signed into the app. You will have to write some code to check for this case.
I also strongly suggest not using a display name as the ID for a document in Cloud Firestore. Since you're using Firebase Authentication, the user already has a unique ID assigned to their account. This is the preferred way to store per-user data.
I found the error:
I called my delete method after I used the user.delete() method which deletes the signed in user, so logically the displayName was also deleted.
I want to update my password value, I will input the username and search for a parent node that would match the username text to change the password.
Here's my code
db = FirebaseDatabase.getInstance().getReference();
logIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
progressDialog.setMessage("Changing Password");
newPassword();
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Change successful.", Toast.LENGTH_LONG).show();
}
});//inside of onCreate method
private void newPassword(){
if(TextUtils.isEmpty(userText.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input username.", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(emailText.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input email.", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(contactText.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input contact no.", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(firstText.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input first name.", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(lastText.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input last name.", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(password.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input password.", Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(retype.getText().toString().trim())){
progressDialog.dismiss();
Toast.makeText(this, "Input retype password.", Toast.LENGTH_LONG).show();
return;
}
db.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String username = userText.getText().toString().trim();
for(DataSnapshot ds: dataSnapshot.getChildren()){
if(username.matches(ds.getKey())){
user.setPassword(password.getText().toString().trim());
ds.getRef().child(username).child("password").setValue(user.getPassword());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("User", databaseError.getMessage());
}
});
}
My question is how to get to the node that I want to change its values, and every time I pressed the button, the password's value won't change.
Thanks for your help.
EDITED
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forgot_password);
...
progressDialog = new ProgressDialog(this);
db = FirebaseDatabase.getInstance().getReference();
db.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
username = (String)dataSnapshot.child(userText.getText().toString().trim()).child("username").getValue();
address = (String)dataSnapshot.child(userText.getText().toString().trim()).child("address").getValue();
contact = (String)dataSnapshot.child(userText.getText().toString().trim()).child("contact").getValue();
email = (String)dataSnapshot.child(userText.getText().toString().trim()).child("email").getValue();
first = (String)dataSnapshot.child(userText.getText().toString().trim()).child("first").getValue();
last = (String)dataSnapshot.child(userText.getText().toString().trim()).child("last").getValue();
pass = passwordText.getText().toString().trim();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ForgotPassword.this, "Database Error", Toast.LENGTH_LONG).show();
Intent i = new Intent(ForgotPassword.this, SignIn.class);
startActivity(i);
}
});
logIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newPassword();
}
});
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(ForgotPassword.this, SignIn.class);
startActivity(i);
}
});
}
private void newPassword(){
...
user = new User(first, last, email, contact, pass, username, address);
db.child("users").child(username).setValue(user);
Toast.makeText(getApplicationContext(), "Change successful.", Toast.LENGTH_LONG).show();
Intent i = new Intent(this, TabMenu.class);
startActivity(i);
}
Every time I start this activity, it will give the error immediately on the onCancelled(DatabaseError){Toast.makeText(..., "Database Error", ...).show();}
If you want to compare two Strings in Java, you need to use equals method and not matches.
matches method tells whether or not this string matches the given regular expression.
An invocation of this method of the form str.matches(regex) yields exactly the same result as the expression
java.util.regex.Pattern.matches(regex, str).
So change this line of code:
username.matches(ds.getKey())
with
username.equals(ds.getKey())
To change the password, you only need to use setValue() method directly on the reference like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("users").child("brian").child("password").setValue("newPassword");