This is all the code with register account with email password, save verify email, save user data into Firestore database. Only the Firestore database can't run.
fAuth.createUserWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
// send verification link
FirebaseUser fuser = fAuth.getCurrentUser();
fuser.sendEmailVerification().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(register.this, "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());
}
});
Toast.makeText(register.this, "User Created.", Toast.LENGTH_SHORT).show();
userID = fAuth.getCurrentUser().getUid();
DocumentReference documentReference = fStore.collection("users").document(userID);
Map<String,Object> user = new HashMap<>();
user.put("fName",fullName);
user.put("email",email);
user.put("phone",phone);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: user Profile is created for "+ userID);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "onFailure: " + e.toString());
}
});
startActivity(new Intent(getApplicationContext(),MainActivity.class));
}
else {
Toast.makeText(register.this, "Error ! " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
}
});
}
});
The Firebase authentication operation is asynchronous. This means that you can be sure that authentication succeeded only when the onSuccess() method fires. Since you say that the authentication process successfully completes, your first onSuccess() is triggered. Your second onSuccess() is not triggered because the code that corresponds to the addition of data to Firestore is outside the callback, hence that behavior. To solve this, all the code that exists outside the callback should be moved inside the first onSuccess() as explained in the following line of code:
fAuth
.createUserWithEmailAndPassword(email,password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
// send verification link
FirebaseUser fuser = fAuth.getCurrentUser();
fuser.sendEmailVerification().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(register.this, "Verification Email Has been Sent.", Toast.LENGTH_SHORT).show();
Toast.makeText(register.this, "User Created.", Toast.LENGTH_SHORT).show();
//Moved code 👈👈👈
userID = fAuth.getCurrentUser().getUid();
DocumentReference documentReference = fStore.collection("users").document(userID);
Map<String,Object> user = new HashMap<>();
user.put("fName",fullName);
user.put("email",email);
user.put("phone",phone);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: user Profile is created for "+ userID);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "onFailure: " + e.toString());
}
});
startActivity(new Intent(getApplicationContext(),MainActivity.class));
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "onFailure: Email not sent " + e.getMessage());
}
});
} else {
Toast.makeText(register.this, "Error ! " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
}
});
In this way, you be able to write the data to Firestore when the authentication process is completed.
Related
i want to accsess my firebase collection but somehow it didnt work on this java file, in otherwise i had another java file on my android project thats containts the same syntax and its actually work.. i dont have any idea to solve this line
on Signupn.java (worked)
fAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(SignUp.this, "User Created", Toast.LENGTH_SHORT).show();
userId = fAuth.getCurrentUser().getUid();
DocumentReference documentReference =fStore.collection("users").document(userId);
Map<String,Object> user =new HashMap<>();
user.put("fName",fullName);
user.put("email",email);
user.put("phone",phone);
documentReference.set(user).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Log.d(TAG,"onSuccess: user Profile is created for "+ userId);
}
});
startActivity(new Intent(getApplicationContext(), MainActivity.class));
}else{
Toast.makeText(SignUp.this, "Error!"+task.getException().getMessage(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
}
});
on EditProfile.java (error)
saveBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (editFullName.getText().toString().isEmpty() || editEmail.getText().toString().isEmpty()
|| editPhone.getText().toString().isEmpty()) {
Toast.makeText(EditProfile.this, "All Fields Are Required.", Toast.LENGTH_SHORT).show();
return;
}
String email = editEmail.getText().toString();
user.updateEmail(email).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
DocumentReference docRef = fStore.collection("users").document(user.getUid());
Map<String, Object> edited = new HashMap<>();
edited.put("email", email);
edited.put("fName", editFullName.getText().toString());
edited.put("phone", editPhone.getText().toString());
docRef.update(edited);
Toast.makeText(EditProfile.this, "Email Changed Successfully.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(EditProfile.this, "Error!", Toast.LENGTH_SHORT).show();
}
});
}
});
here is where the error line
DocumentReference docRef = fStore.collection("users").document(user.getUid());
in collection sentence.
this picture from editProfile.java
this picture from signup.java
thank you for your value answers, any answer i really apriciate it.
Please verify your dataStype for fstore object in both classes or post full code wherever you are declaring the fstore and intializing it
I am trying to update my email from FireBase, how can I achive this? updateEmail looks like has been depreacated?
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
AuthCredential credential= EmailAuthProvider.getCredential(user.getEmail(),edtPassword.getText().toString());
user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if(task.isSuccessful()){
FirebaseAuth.getInstance().fetchSignInMethodsForEmail(edtEmail.getText().toString())
.addOnCompleteListener(new OnCompleteListener<SignInMethodQueryResult>() {
#Override
public void onComplete(#NonNull Task<SignInMethodQueryResult> task) {
if(task.isSuccessful()){
if(task.getResult().getSignInMethods().size()==0){
Here--------------------------------->
}else {
Toast.makeText(AccountSettingsActivity.this,"The Email is alread in use",Toast.LENGTH_SHORT).show();
}
}else {
Toast.makeText(AccountSettingsActivity.this,"Task is not successfull in fetch",Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressBar.setVisibility(View.GONE);
Toast.makeText(AccountSettingsActivity.this,"Unable to edt email",Toast.LENGTH_SHORT).show();
}
});
}else {
Toast.makeText(AccountSettingsActivity.this,"Task is not successfull", Toast.LENGTH_LONG).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressBar.setVisibility(View.GONE);
Toast.makeText(AccountSettingsActivity.this,"Unable to update email failure",Toast.LENGTH_LONG).show();
}
});
}
I had the same issu and I found the solution here : How to update email from Firebase in Android?
To retrieve password for credential you can use SharedPreferences.
It worked for me ;)
My app uses FirebaseAuth. In my SignInActivity, on clicking the sign in button, the signInWithEmailAndPassword onCompleteListener starts my DashboardActivity with an Intent. In the DashboardActivity, there is a method which calls FirebaseAuth.getInstance().getCurrentUser().getUid() which crashes my app if the user trying to signIn does not exist.
The question here is: why does the method get called at all if the Intent was not sent? or was the intent sent?
here is my SignInActivity signIn Button code:
signIn.setOnClickListener((new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!email.getText().toString().equals("") && !password.getText().toString().equals("")) {
showProgressBar();
FirebaseAuth.getInstance().signInWithEmailAndPassword(email.getText().toString(), password.getText().toString()).addOnCompleteListener((new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
hideProgressBar();
Toast.makeText(SignInActivity.this, "Signed In", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
startActivity(intent);
finish();
}
})).addOnFailureListener((new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
hideProgressBar();
Toast.makeText(SignInActivity.this, "Failed to Sign In", Toast.LENGTH_SHORT).show();
}
}));
} else {
Toast.makeText(SignInActivity.this, "please fill all fields", Toast.LENGTH_SHORT).show();
}
}
}));
DashboardActivity code (that crashes the app):
private void queryDB() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference.child(getString(R.string.users))
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child("securityLevel");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String secLevel = dataSnapshot.getValue(String.class);
if (secLevel.equals("1")) {
fab.hide();
} else {
fab.show();
}
Log.d(TAG, "onDataChange: +-+ " + secLevel);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
The Logcat:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at com.quwaysim.regapp.DashboardActivity.queryDB(DashboardActivity.java:191)
at com.quwaysim.regapp.DashboardActivity.onCreate(DashboardActivity.java:60)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127).......
OnComplete will execute even if the authorization passed or not. You need to add OnSuccessListener and handle the intent there.
You are not checking if task is successful or not. You have to do it like:
#Override
public void onClick(View view) {
if (!email.getText().toString().equals("") && !password.getText().toString().equals("")) {
showProgressBar();
FirebaseAuth.getInstance().signInWithEmailAndPassword(email.getText().toString(), password.getText().toString()).addOnCompleteListener((new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful() && task.getResult() != null){
hideProgressBar();
Toast.makeText(SignInActivity.this, "Signed In", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
startActivity(intent);
finish();
}
}
})).addOnFailureListener((new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
hideProgressBar();
Toast.makeText(SignInActivity.this, "Failed to Sign In", Toast.LENGTH_SHORT).show();
}
}));
} else {
Toast.makeText(SignInActivity.this, "please fill all fields", Toast.LENGTH_SHORT).show();
}
}
}));
I am using Firebase upload and I want to write the uploaded method in a class out of the activity as I want to use it several times and at the same time I want to use ProgressBar that shows the progress and as it is known we can't use findViewById out of activity or Fragment.
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getError();
float progress = (float) ((100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount());
System.out.println("Upload is " + progress + "% done");
**Here I wanna use a progressBar**
}
}).addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
#Override
public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
System.out.println("Upload is paused");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
int errorCode = ((StorageException) exception).getErrorCode();
String errorMessage = exception.getMessage();
// test the errorCode and errorMessage, and handle accordingly
Log.d(TAG, "onSuccess: The photo has NOT been uploaded" + errorCode + errorMessage);
Toast.makeText(mContext, "Sorry the photo has not been uploaded .. Please Try again", Toast.LENGTH_SHORT);
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
circleProgressBar.setVisibility(View.GONE);
Log.d(TAG, "onSuccess: The photo is being uploaded");
Toast.makeText(mContext, "The photo has been uploaded successfully", Toast.LENGTH_SHORT).show();
//
}
}).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
// Continue with the task to get the download URL
return ref.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
if (downloadUri != null){
String photoStringUrl = downloadUri.toString();
Log.d(TAG, "onComplete: Upload " + photoStringUrl);
//Inserting the profile photo into database {user_profile_account}
firebaseUtilities.saveProfilePhotoToDatabase(photoStringUrl);
}
}
You can pass Activity as a parameter instead of Context.
private void userSign() {
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
String message = Objects.requireNonNull(task.getException()).getMessage();
Toast.makeText(Start.this, "Error occured: " + message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
else
{
Query DatabaseQuery = databaseReference.child("Users").child("Customer").orderByChild("email").equalTo(CLemail.getText().toString().trim());
DatabaseQuery.addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
if (dataSnapshot.exists())
{
for (DataSnapshot user : dataSnapshot.getChildren())
{
User usersBean = user.getValue(User.class);
if (!usersBean.password.equals(CLpassword.getText().toString().trim()))
{
CLpassword.setError("Password is Wrong!");
CLpassword.requestFocus();
}
else
{
Intent intent = new Intent(Start.this, Home.class);
startActivity(intent);
dialog.setMessage("Loging please wait");
dialog.setIndeterminate(true);
dialog.show();
}
}
}
else {
Toast.makeText(Start.this, "User not found", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError)
{
Toast.makeText(Start.this, "Email not found", Toast.LENGTH_LONG).show();
}
});
dialog.dismiss();
Intent intent = new Intent(Start.this, Home.class);
startActivity(intent);
}
}
});
}