authentication problem in fire base using android studio - java

I am working on a project which required firebase utilities so I did all those things required but my authentication is not taking place and thereby my data is not being uploaded in the firestore. I have tried many things and found that during the time of execution my onComplete listener is calling failure and thus a toast is popped authentication failure so I think the main problem lies in the onComplete listener but I couldn't fix it. My code is as follows-
*
private TextView username;
private TextView password;
private AutoCompleteTextView email;
private ProgressBar progress_bar;
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener authStateListener;
private FirebaseUser currentUser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
username = findViewById(R.id.username_account);
password = findViewById(R.id.password_account);
email = findViewById(R.id.email_account);
Button create_account = findViewById(R.id.create_acct_button);
progress_bar = findViewById(R.id.create_acct_progress);
firebaseAuth = FirebaseAuth.getInstance();
create_account.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!TextUtils.isEmpty(email.getText().toString())
&& !TextUtils.isEmpty(password.getText().toString())
&& !TextUtils.isEmpty(username.getText().toString())) {
String Email = email.getText().toString().trim();
String Password = password.getText().toString().trim();
String Username = username.getText().toString().trim();
createUserEmailAccount(Email, Password, Username);
} else {
Toast.makeText(CreateAccountActivity.this,
"Empty Fields Not Allowed",
Toast.LENGTH_LONG)
.show();
}
}
});
}
private void createUserEmailAccount(String email, String password, final String username) {
if (!TextUtils.isEmpty(email) && !TextUtils.isEmpty(password) && !TextUtils.isEmpty(username)) {
progress_bar.setVisibility((View.VISIBLE));
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener( CreateAccountActivity.this,new OnCompleteListener<AuthResult>() {
#Override
public void onComplete( #NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Map<String, Object> userobj = new HashMap<>();
userobj.put("userId", "currentuserId");
userobj.put("username", username);
db.collection("journal")
.add(userobj)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Log.d(TAG, "DocumentSnapshot successfully written!");
progress_bar.setVisibility(View.INVISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error writing document", e);
}
});
} else {
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(CreateAccountActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
progress_bar.setVisibility(View.INVISIBLE);
}
}
});
}
}
}*

Related

Firebase is not sending OTP code on my Phone number | Java | Android Studio

I'm trying to authenticate user with phone number using the firebase Authentication method. But it is showing me error after some time by running the code. And I think the sendVerificationCodeToUser() function is not working properly.
package com.example.foodapp;
import ...
public class PhoneVerification<phoneAuthProvider> extends AppCompatActivity {
String verificationCodeBySystem;
Button btn_verify;
EditText phoneenteredbyuser;
ProgressBar progressbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_verification);
btn_verify = findViewById(R.id.btn_verify);
phoneenteredbyuser = findViewById(R.id.txt_otp);
progressbar = findViewById(R.id.progressbar);
progressbar.setVisibility(View.GONE);
String phoneNo = getIntent().getStringExtra("phone");
sendVerificationCodeToUser(phoneNo);
btn_verify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String code= phoneenteredbyuser.toString();
if(code.isEmpty() || code.length()< 6){
phoneenteredbyuser.setError("Wrong OTP...");
phoneenteredbyuser.requestFocus();
return;
}
progressbar.setVisibility(View.VISIBLE);
verifyCode(code);
}
});
}
private void sendVerificationCodeToUser(String phoneNo) {
FirebaseAuth mAuth= FirebaseAuth.getInstance();
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber("+92" + phoneNo) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override //Entering OTP by manual way
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
verificationCodeBySystem = s;
}
#Override // Automatically Verifying the OTP by system.
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
String code = phoneAuthCredential.getSmsCode();
if (code != null) {
progressbar.setVisibility(View.VISIBLE);
verifyCode(code);
}
}
#Override //In case of error this code will run.
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(PhoneVerification.this, "Error Occured", Toast.LENGTH_SHORT).show();
}
};
private void verifyCode(String codeByUser) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationCodeBySystem, codeByUser);
signInUserByCredentials(credential);
}
private void signInUserByCredentials(PhoneAuthCredential credential) {
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(PhoneVerification.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(PhoneVerification.this, "Your Account has been created successfully!", Toast.LENGTH_SHORT).show();
//Perform Your required action here to either let the user sign In or do something required
Intent intent = new Intent(getApplicationContext(), User_Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
} else {
Toast.makeText(PhoneVerification.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}

Firebase createUserWithEmailAndPassword task.isSuccessful()

I'm creating an Android application and am implementing the login / register functionality.
I'm at the stage where the register activity is successfully creating user entries in my Firebase application, however, I can't seem to track if the task was successful.
private void startRegister() {
String email = mEmailField.getText().toString();
String password = mPasswordField.getText().toString();
String confirmPassword = mConfirmPassword.getText().toString();
// Check that fields are not empty
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password) || TextUtils.isEmpty(confirmPassword)) {
Toast.makeText(Register.this, "Email, password or confirm password field cannot be empty.", Toast.LENGTH_LONG).show();
} else if (!password.equals(confirmPassword)) {
Toast.makeText(Register.this, "Password and confirm password should match", Toast.LENGTH_LONG).show();
} else {
mAuth.createUserWithEmailAndPassword(email, password).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Toast.makeText(Register.this, "Success", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Register.this, "Failure", Toast.LENGTH_LONG).show();
}
});
}
}
Both the if !task.isSuccessful() or else blocks ever get reached but the user is created in Firebase. Any ideas why I can't track the success/if it failed?
IN COMPARISON:
This is working in my login class.
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(Login.this, "Credentials error, user may not exist.", Toast.LENGTH_LONG).show();
}
}
});
Hard to say what's going with the current way of implementation.
Try adding a onSuccess directly
mAuth.createUserWithEmailAndPassword(email, pass).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
//done
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
//display toast if registering failed
ToastRect.failed(RegisterActivity.this, getString(R.string.app_activities_error_text)
}
});
public class Register extends AppCompatActivity {
private EditText mEmailField;
private EditText mPasswordField;
private EditText mConfirmPassword;
private Button mRegisterButton;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FirebaseApp.initializeApp(this);
setContentView(R.layout.activity_register);
mEmailField = findViewById(R.id.registerEmailField);
mPasswordField = findViewById(R.id.registerPasswordField);
mConfirmPassword = findViewById(R.id.registerConfirmPassword);
mRegisterButton = findViewById(R.id.registerButton);
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null) {
startActivity(new Intent(Register.this, UploadActivity.class));
}
}
};
// https://stackoverflow.com/questions/10936042/how-to-open-layout-on-button-click-android
Button register = (Button) findViewById(R.id.navigate_to_login);
register.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), Login.class);
startActivityForResult(myIntent, 0);
}
});
mRegisterButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startRegister();
}
});
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
private void startRegister() {
String email = mEmailField.getText().toString();
String password = mPasswordField.getText().toString();
String confirmPassword = mConfirmPassword.getText().toString();
// Check that fields are not empty
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password) || TextUtils.isEmpty(confirmPassword)) {
Toast.makeText(Register.this, "Email, password or confirm password field cannot be empty.", Toast.LENGTH_LONG).show();
} else if (!password.equals(confirmPassword)) {
Toast.makeText(Register.this, "Password and confirm password should match", Toast.LENGTH_LONG).show();
} else {
mAuth.createUserWithEmailAndPassword(email, password).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
Toast.makeText(Register.this, "Success", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Register.this, "Failure", Toast.LENGTH_LONG).show();
}
});
}
}
}
To confirm the FirebaseAuth.AuthStateListener() was kicking in. This was a bad copy and paste job from the my Login class. This was stopping me handle the successful user creation.
The fix then looked like:
public class Register extends AppCompatActivity {
private EditText mEmailField;
private EditText mPasswordField;
private EditText mConfirmPassword;
private Button mRegisterButton;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FirebaseApp.initializeApp(this);
setContentView(R.layout.activity_register);
mEmailField = findViewById(R.id.registerEmailField);
mPasswordField = findViewById(R.id.registerPasswordField);
mConfirmPassword = findViewById(R.id.registerConfirmPassword);
mRegisterButton = findViewById(R.id.registerButton);
mAuth = FirebaseAuth.getInstance();
// https://stackoverflow.com/questions/10936042/how-to-open-layout-on-button-click-android
Button register = (Button) findViewById(R.id.navigate_to_login);
register.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), Login.class);
startActivityForResult(myIntent, 0);
}
});
mRegisterButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startRegister();
}
});
}
#Override
protected void onStart() {
super.onStart();
}
private void startRegister() {
String email = mEmailField.getText().toString();
String password = mPasswordField.getText().toString();
String confirmPassword = mConfirmPassword.getText().toString();
// Check that fields are not empty
if (TextUtils.isEmpty(email) || TextUtils.isEmpty(password) || TextUtils.isEmpty(confirmPassword)) {
Toast.makeText(Register.this, "Email, password or confirm password field cannot be empty.", Toast.LENGTH_LONG).show();
} else if (!password.equals(confirmPassword)) {
Toast.makeText(Register.this, "Password and confirm password should match", Toast.LENGTH_LONG).show();
} else {
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(Register.this, "Password and confirm password should match", Toast.LENGTH_LONG).show();
}
}
});
}
}
}

Cannot create PhoneAuthCredential without verificationProof?

I have followed the guideline of firebase docs to implement login into my app but there is a problem while signup, the app is crashing and the catlog showing the following erros :
Process: app, PID: 12830
java.lang.IllegalArgumentException: Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, ortemprary proof.
at com.google.android.gms.common.internal.Preconditions.checkArgument(Unknown Source)
at com.google.firebase.auth.PhoneAuthCredential.<init>(Unknown Source)
at com.google.firebase.auth.PhoneAuthProvider.getCredential(Unknown Source)
at app.MainActivity.verifyPhoneNumberWithCode(MainActivity.java:132)
at app.MainActivity.onClick(MainActivity.java:110)
at android.view.View.performClick(View.java:4803)
at android.view.View$PerformClick.run(View.java:20102)
at android.os.Handler.handleCallback(Handler.java:810)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:189)
at android.app.ActivityThread.main(ActivityThread.java:5532)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
I've tried to see other code examples but they are simmiler to my code but still my app crashes with the same error.
and this is my code i wrote using the guidline of firebase documents :
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private FirebaseAuth mAuth;
private String mVerificationId;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
Button login,verify,signout;
EditText number;
EditText code;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
login = findViewById(R.id.btnlogin);
verify = findViewById(R.id.btnverify);
signout = findViewById(R.id.btnsignout);
number = findViewById(R.id.editnumber);
code = findViewById(R.id.editcode);
login.setOnClickListener(this);
verify.setOnClickListener(this);
signout.setOnClickListener(this);
mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
signInWithPhoneAuthCredential(phoneAuthCredential);
}
#Override
public void onVerificationFailed(FirebaseException e) {
Toast.makeText(MainActivity.this, "Error" + e.toString(), Toast.LENGTH_SHORT).show();
if (e instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(MainActivity.this, "Invalid Request " + e.toString(), Toast.LENGTH_SHORT).show();
} else if (e instanceof FirebaseTooManyRequestsException) {
Toast.makeText(MainActivity.this, "The SMS quota for the project has been exceeded " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCodeSent(String vId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
Toast.makeText(MainActivity.this, "Code Sent" + vId, Toast.LENGTH_SHORT).show();
number.setText("");
mVerificationId = vId;
}
};
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential phoneAuthCredential) {
mAuth.signInWithCredential(phoneAuthCredential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isComplete()){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String uid = null;
if (user != null) {
uid = user.getUid();
}
Toast.makeText(MainActivity.this, "Signed In", Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, uid, Toast.LENGTH_SHORT).show();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(MainActivity.this, "Invalid Code", Toast.LENGTH_SHORT).show();
}
}
}
});
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnlogin: {
String phonenumber = number.getText().toString();
startPhoneNumberVerification(phonenumber);
}
case R.id.btnverify: {
String vCode = code.getText().toString();
verifyPhoneNumberWithCode(mVerificationId, vCode);
}
case R.id.btnsignout: {
mAuth.signOut();
}
}
}
private void startPhoneNumberVerification(String phoneNumber) {
PhoneAuthProvider.getInstance().verifyPhoneNumber(phoneNumber, 60, TimeUnit.SECONDS, this, mCallbacks);
}
private void verifyPhoneNumberWithCode(String verificationId, String code) {
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
signInWithPhoneAuthCredential(credential);
}
}
The Above code is sending the otp to the given number but it crashes and cat-log shows the error mentioned above.
Please try to help me to figure out what is the error in my code rather referring to other codes.
you are getting number without country code like +91 use with country code or use
String withCountryCode = "+91"+code
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, withCountryCode);
signInWithPhoneAuthCredential(credential);

Creating link between Firebase real-time database and authenticated users

So far I have successfully implemented Firebase within my Android application, where I can add users to the Authentication portal through a SignUpActivity, and also add maintenance issues to the real-time database through a MaintenanceActivity.
However, at present, none of the database data is linked to specific users, which is what I want to achieve. So essentially at the moment when I log in as an arbitrary user, the same data will always come up.
Presumably, and having read several other threads on this, the User UID will be required here and will need to be present for every maintenance record.
I'm not sure, however, how I can implement this. Possibly a layer of authentication needs implemented into the MainActivity?
Finding it hard to get my head around this, so any help on this would be much appreciated.
SignUpActivity
mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
final DatabaseReference[] ref = new DatabaseReference[1];
final FirebaseUser[] mCurrentUser = new FirebaseUser[1];
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toasty.info(getApplicationContext(), "creation of account was: " + task.isSuccessful(), Toast.LENGTH_SHORT).show();
if (task.isSuccessful()) {
mCurrentUser[0] = task.getResult().getUser();
ref[0] =mDatabase.child(mCurrentUser[0].getUid());
ref[0].child("email").setValue(email);
Intent intent = new Intent(SignUpActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
});
You can implement it like this:
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
DatabaseReference ref;
FirebaseUser mCurrentUser;
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toasty.info(getApplicationContext(), "creation of account was: " + task.isSuccessful(), Toast.LENGTH_SHORT).show();
if (task.isSuccessful()) {
mCurrentUser= task.getResult().getUser();
ref=mDatabase.child(mCurrentUser.getUid());
ref.child("email").setValue(email);
ref.child("name").setValue(name);
}
});
You can implement it like the above, then in your db you will have:
Users
userid
name: userx
email: userx#gmail.com
After you authenticate the user using createUserWithEmailAndPassword(email, password), you can then retrieve the email and name, and whatever extra data was written and send it to the database.
This mCurrentUser.getUid() will give you the userid, that you can use in the database.
After adding your project to the firebase
U can also try this.
public class RegisterActivity extends AppCompatActivity implements
View.OnClickListener {
private static final String TAG = "MAGIC";
Firebase mref =null;
private User user;
private EditText email;
private EditText password;
private FirebaseAuth mAuth;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Firebase.setAndroidContext(this);
mAuth = FirebaseAuth.getInstance();
}
#Override
protected void onStart() {
super.onStart();
email = (EditText) findViewById(R.id.edit_text_new_email);
password = (EditText) findViewById(R.id.edit_text_new_password);
}
#Override
public void onStop() {
super.onStop();
}
//This method sets up a new User by fetching the user entered details.
protected void setUpUser() {
user = new User();
user.setEmail(email.getText().toString().trim());
user.setPassword(password.getText().toString().trim());
}
#Override
public void onClick(View v) {
//paste your firebase database link address here.
mref = new Firebase("https://citypride-97902.firebaseio.com/");
createNewAccount(email.getText().toString(),
password.getText().toString());
}
private void createNewAccount(String email, String password) {
Log.d(TAG, "createNewAccount:" + email);
if (!validateForm()) {
return;
}
showProgressDialog();
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "Register Successfully " + task.isSuccessful());
hideProgressDialog();
if (!task.isSuccessful()) {
Toast.makeText(RegisterActivity.this, "Registration failed.",
Toast.LENGTH_SHORT).show();
hideProgressDialog();
} else {
onAuthenticationSuccess(task.getResult().getUser());
Toast.makeText(RegisterActivity.this, "Register Successful.",
Toast.LENGTH_SHORT).show();
} hideProgressDialog();
}
});
}
private void onAuthenticationSuccess(FirebaseUser mUser) {
// Write new user
saveNewUser(mUser.getUid(), user.getEmail(), user.getPassword());
signOut();
// Go to LoginActivity
Intent i =new Intent(LoginActivity.this, YourActivity.class);
startActivity(i);
}
private void saveNewUser(String userId,
String email, String password) {
User user = new User(userId,email,password);
mref.child("Users").child(name).setValue(user);
}
private void signOut() {
mAuth.signOut();
}
//This method, validates email address and password
private boolean validateForm() {
boolean valid = true;
String userEmail = email.getText().toString();
if (TextUtils.isEmpty(userEmail)) {
email.setError("Required.");
valid = false;
} else {
email.setError(null);
}
String userPassword = password.getText().toString();
if (TextUtils.isEmpty(userPassword)) {
password.setError("Required.");
valid = false;
} else {
password.setError(null);
}
if(!Patterns.EMAIL_ADDRESS.matcher(userEmail).matches()){
Toast.makeText(getApplicationContext(),"please enter valid
email",Toast.LENGTH_LONG).show();
}
if (userEmail.isEmpty() && userPassword.isEmpty()){
Toast.makeText(getApplicationContext(),"all fields are
mandatory",Toast.LENGTH_LONG).show();
}
return valid;
}
public void showProgressDialog() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Loading");
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
public void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
}
Below is User class
class User {
private String id;
private String email;
private String password;
public User() {
}
public User(String id,String email, String password) {
this.id = id;
this.email = email;
this.password = password;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
this will show email and password field in your firebase database.

Firebase database entry is only created when breakpoint is set in Android Studio

I have the following SignUp Activity that does not work properly: after the user receives the verification email and tries to sign in, the app crashes with a NullPointerException, as a new user entry in Firebase Realtime Database is not created. I noticed, though, during debugging, that if I set a breakpoint at where generateUser() is defined, a new database entry is created (the app crashes the same way, though).
What could be the solution here?
Any help would be highly appreciated.
Update: The emphasis here is not on NullPointerException, I can handle that. The question is why generateUser() is not being called.
public class SignUpActivity extends AppCompatActivity {
private EditText inputUsername, inputEmail, inputPassword;
private Button btnSignIn, btnSignUp;
private ProgressBar progressBar;
private FirebaseAuth auth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
if (user != null) {
if (user.isEmailVerified()) {
startActivity(new Intent(SignUpActivity.this, MainActivity.class));
finish();
}
}
setContentView(R.layout.activity_sign_up);
btnSignIn = findViewById(R.id.sign_in_button);
btnSignUp = findViewById(R.id.sign_up_button);
inputUsername = findViewById(R.id.username);
inputEmail = findViewById(R.id.email);
inputPassword = findViewById(R.id.password);
progressBar = findViewById(R.id.progressBar);
btnSignIn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(SignUpActivity.this, SignInActivity.class));
}
});
btnSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String username = inputUsername.getText().toString().trim();
final String email = inputEmail.getText().toString().trim();
final String password = inputPassword.getText().toString().trim();
if (TextUtils.isEmpty(username)) {
Toast.makeText(getApplicationContext(), "Enter username!", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "Enter email address!", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "Enter password!", Toast.LENGTH_SHORT).show();
return;
}
if (password.length() < 6) {
Toast.makeText(getApplicationContext(), "Password too short, enter minimum 6 characters!", Toast.LENGTH_SHORT).show();
return;
}
progressBar.setVisibility(View.VISIBLE);
auth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
progressBar.setVisibility(View.GONE);
if (!task.isSuccessful()) {
Toast.makeText(SignUpActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show();
} else {
new GenerateUserAsyncTask().execute(username, email, password, 0);
}
}
});
}
class GenerateUserAsyncTask extends AsyncTask<Object, Void, Void> {
#Override
protected Void doInBackground(Object... params) {
String username = (String) params[0];
String email = (String) params[1];
String password = (String) params[2];
int score = (int) params[3];
generateUser(username, email, password, score);
return null;
}
#Override
protected void onPostExecute(Void result) {
sendVerificationEmail();
}}
});
}
public void sendVerificationEmail() {
FirebaseUser user = auth.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();
auth.signOut();
startActivity(new Intent(SignUpActivity.this, SignInActivity.class));
finish();
} else {
Toast.makeText(SignUpActivity.this, "Failed to send email!", Toast.LENGTH_SHORT).show();
}
progressBar.setVisibility(View.GONE);
}
});
}
}
public void generateUser(String username, String email, String password, int score) {
FirebaseDatabase database = Utils.getDatabase();
DatabaseReference users = database.getReference("users");
User user = new User(username, email, password, score);
users.child(auth.getUid()).setValue(user);
}
}
I have found the solution. The problem is caused by the Realtime Database security rules: they only allow users to write to the database if they are authenticated. In my code, though, where generateUser() is called, users are not fully authenticated yet. So I need to generate new entries in the database after the user has clicked on the link in the verification email.

Categories

Resources