Junit Testing for an Android Activity - android

Does any one have any experience with creating unit-test for the On Create and OnClick method in java, using Android Studio? I use data from my Firebasedatabase.
I think I have to use Mock-object, but I don't knot where to start.
Under is the code from my class LoginActivity
public class LoginActivity extends AppCompatActivity implements View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mfireBaseAuth = FirebaseAuth.getInstance();
mDatabase = FirebaseDatabase.getInstance().getReference();
mProgressDialog = new ProgressDialog(this);
editTextEmail = (EditText) findViewById(R.id.editTextEmail);
editTextPassword = (EditText) findViewById(R.id.editTextPassword);
buttonSignIn = (Button) findViewById(R.id.buttonSignIn);
textViewSignUp = (TextView) findViewById(R.id.textViewSignUp);
buttonSignIn.setOnClickListener(this);
textViewSignUp.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v == buttonSignIn){
usersignin();
}
if(v==textViewSignUp){
startActivity(new Intent(this, RegisterActivity.class));
}
}
private void usersignin() {
String email = editTextEmail.getText().toString().trim();
String password = editTextPassword.getText().toString().trim();
if(TextUtils.isEmpty(email)){
Toast.makeText(this, "Please enter Email", Toast.LENGTH_SHORT).show();
return;
}
if(TextUtils.isEmpty(password)){
Toast.makeText(this, "Please enter password", Toast.LENGTH_SHORT).show();
return;
}
mProgressDialog.setMessage("Logging in. Please wait...");
mProgressDialog.show();
mfireBaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
mProgressDialog.dismiss();
if(task.isSuccessful()){
getSignedInUserProfile();
}
}
});
}
private void getSignedInUserProfile() {
DatabaseReference reference = mDatabase;//.child("eduback-2feef");
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
userID = firebaseUser.getUid();
reference.child("Users").child(userID).child("User info").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if(user != null) {
// Save if the user is student or prof in shared prefs.
PreferenceHelper helper = new PreferenceHelper(getBaseContext());
helper.setIsStudent(user.isStudent);
checkStudentOrProfessor(user);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Ups vis error
}
});
}
private void checkStudentOrProfessor(User user) {
Intent i;
if (user.isStudent ) {
i = new Intent(this, MainActivityStudent.class);
} else {
i = new Intent(this, MainActivityProfessor.class);
}
startActivity(i);
}
}

The Mockito mocking framework for Java offers compatibility with Android unit testing.
You can configure mock objects to return some specific value when invoked.
You don't need to test Firebasedatabass.
But you have to make Firebasedatabase wrapper class for yours view
Wrapper class have to include variable(userID, user.isStudent)

Related

Home activity with nav drawer menu does not open after login

I created a Login android app, connected to firebase Real time database and works perfectly (Users has been created successfully).
From LoginActivity, users must go to HomeActivity, which has a navigation drawer menu, but does not work.
I tried to change the activity destination, so after login, I tried to open a TrialActivity and works perfectly.
What could be the problem?
LoginActivity
public class LoginActivity extends AppCompatActivity {
private EditText InputNumber, InputPaswd;
private Button LoginBtn;
private ProgressDialog loadingBar;
private String parentDBName = "Users";
private TextView AdminLink, NotAdminLink;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
InputNumber = (EditText) findViewById(R.id.login_phone_numb_input);
InputPaswd = (EditText) findViewById(R.id.login_Password);
LoginBtn = (Button) findViewById(R.id.login_btn);
loadingBar = new ProgressDialog(this);
AdminLink = (TextView) findViewById(R.id.admin_panel_link);
NotAdminLink = (TextView) findViewById(R.id.not_admin_panel_link);
LoginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LoginUser();
}
});
AdminLink.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LoginBtn.setText("Login Admin");
AdminLink.setVisibility(View.INVISIBLE);
NotAdminLink.setVisibility(View.VISIBLE);
parentDBName="Admins";
}
});
NotAdminLink.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LoginBtn.setText("Login");
AdminLink.setVisibility(View.VISIBLE);
NotAdminLink.setVisibility(View.INVISIBLE);
parentDBName="Users";
}
});
}
private void LoginUser() {
String phone = InputNumber.getText().toString();
String password = InputPaswd.getText().toString();
// InputNumber.setText("3791881336");
//InputPaswd.setText("1234");
if (TextUtils.isEmpty(phone)) {
Toast.makeText(this,"Please enter your number",Toast.LENGTH_SHORT);
}
else if (TextUtils.isEmpty(password)){
Toast.makeText(this,"Please enter your password",Toast.LENGTH_SHORT);
}
else {
loadingBar.setTitle("Log in");
loadingBar.setMessage("Please wait, loading");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
AllowAccessToAccount( phone, password);
}
}
private void AllowAccessToAccount(String phone, String password) {
final DatabaseReference RootRef;
DatabaseReference reference = FirebaseDatabase.getInstance( "https://ecommerce-bdb44-default-rtdb.europe-west1.firebasedatabase.app").getReference();
RootRef = FirebaseDatabase.getInstance().getReference();
RootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.child(parentDBName).child(phone).exists()){
Users userData = snapshot.child(parentDBName).child(phone).getValue(Users.class);
if (userData.getPhone().equals(phone)){
if (userData.getPassword().equals(password)){
if (parentDBName.equals("Admins")){
Toast.makeText(LoginActivity.this, "Logged in Successfully", Toast.LENGTH_SHORT);
loadingBar.dismiss();
Intent intent = new Intent(LoginActivity.this, AdminActivity.class);
startActivity(intent);
}
else if
(parentDBName.equals("Users")){
Toast.makeText(LoginActivity.this, "Logged in Successfully", Toast.LENGTH_SHORT);
loadingBar.dismiss();
Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
startActivity(intent);
}
}
}
}
else {
Toast.makeText(LoginActivity.this, "Account with" + phone + "do not exist",Toast.LENGTH_SHORT);
loadingBar.dismiss();
Toast.makeText(LoginActivity.this, "You need to create an account",Toast.LENGTH_SHORT);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}

Don't display login screen for user after signing in - Android Studio [duplicate]

This question already has answers here:
One time login in app - FirebaseAuth
(3 answers)
Closed 3 years ago.
I have an app that the home screen is the login activity, I would like that after the user logs in this screen will no longer be displayed even if the user is using the back button on the phone. and always keep him logged in when you open the app. any solution not being sharedpreferences?
something that I can implement in mainactivity to solve this issue? in this case, the user would only return to activitylogin if he presses the exit button. the button event I do myself, I really need help with this method so that the user can no longer access the login page, not even by clicking back on the cell phone. any help is welcome.
my manifest is like this
<activity
android:name=".LoginActivity"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
LOGIN ACTIVITY CODE
public class LoginActivity extends AppCompatActivity {
private EditText emailTV, passwordTV;
private Button loginBtn;
private ProgressBar progressBar;
private FirebaseAuth mAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mAuth = FirebaseAuth.getInstance();
initializeUI();
loginBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginUserAccount();
}
});
Button registrar = (Button)findViewById(R.id.registrar);
registrar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(LoginActivity.this, RegistroActivity.class));
}
});
}
private void loginUserAccount() {
progressBar.setVisibility(View.VISIBLE);
String email, password;
email = emailTV.getText().toString();
password = passwordTV.getText().toString();
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "INSIRA E-MAIL...", Toast.LENGTH_LONG).show();
return;
}
if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "INSIRA SENHA!", Toast.LENGTH_LONG).show();
return;
}
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(getApplicationContext(), "LOGADO COM SUCESSO!", Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.GONE);
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}
else {
Toast.makeText(getApplicationContext(), "FALHA AO LOGAR TENTE NOVAMENTE", Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.GONE);
}
}
});
}
private void initializeUI() {
emailTV = (EditText) findViewById(R.id.email);
passwordTV = (EditText) findViewById(R.id.password);
loginBtn = (Button) findViewById(R.id.login);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
}
}
MAINACTIVITY CODE
public class MainActivity extends AppCompatActivity {
private FirebaseAuth mAuth;
Button btn_send;
TextView et_contact;
TextView et_message;
TextView Uemail;
FirebaseAuth firebaseAuth;
FirebaseUser firebaseUser;
FirebaseDatabase firebaseDatabase;
private ValueEventListener valueEventListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
btn_send = (Button)findViewById(R.id.btn_send);
et_contact = (TextView) findViewById(R.id.et_contact);
et_message = (TextView) findViewById(R.id.et_message);
Uemail = (TextView) findViewById(R.id.Uemail);
firebaseAuth = FirebaseAuth.getInstance();
firebaseUser = firebaseAuth.getCurrentUser();
//textView52.setText(firebaseUser.getEmail());
firebaseDatabase = firebaseDatabase;
Uemail.setText(firebaseUser.getEmail());
PermissionToConnect();
btn_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = et_contact.getText().toString();
String message = et_message.getText().toString();
try{
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(number, null, message, null, null);
Toast.makeText(MainActivity.this, "Sent", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(MainActivity.this, "Sending Failed", Toast.LENGTH_SHORT).show();
}
}
});
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String userUid = user.getUid();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("Users").child(userUid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String data = (String) dataSnapshot.child("name").getValue();
et_message.setText(data);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});}
private void PermissionToConnect(){
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.SEND_SMS)){
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.SEND_SMS}, 1);
}else{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.SEND_SMS}, 1);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Access", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Denied", Toast.LENGTH_SHORT).show();
}
}
}
}
There are many ways you can do this. What I would suggest is don't make the login activity your main/launch activity. Instead, create an activity that will instantiate Firebase and check if the user has already logged in. If it has, launch whichever activity a logged in user should see, if it hasn't, launch the log in screen.

two different app logins on single Firebase project Problem

I have a Problem in the login. Basically, I tell you my scenario.
I have two apps both are connected with a single firebase project.
One app contains driver login and other app contain customer login
When I open a customer app and register the new customer. The customer is successfully registered. And then I open the driver app and entered the customer credential means (Customer email & password) its login successfully and open the driver activity and vice-versa.
how to fix this issue I am using firebase.
customer login activity
public class CustomerLoginActivity extends AppCompatActivity {
private EditText mEmail, mPassword;
private Button mLogin, mRegistration;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener firebaseAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_customer_login);
mAuth = FirebaseAuth.getInstance();
firebaseAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user!=null ){
Intent intent = new Intent(CustomerLoginActivity.this, CustomerMapActivity.class);
startActivity(intent);
finish();
return;
}
}
};
mEmail = (EditText) findViewById(R.id.email);
mPassword = (EditText) findViewById(R.id.password);
mLogin = (Button) findViewById(R.id.login);
mRegistration = (Button) findViewById(R.id.registration);
mRegistration.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(CustomerLoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()){
Toast.makeText(CustomerLoginActivity.this, "sign up error", Toast.LENGTH_SHORT).show();
}else{
String user_id = mAuth.getCurrentUser().getUid();
DatabaseReference current_user_db = FirebaseDatabase.getInstance().getReference().child("Users").child("Customers").child(user_id);
current_user_db.setValue(true);
}
}
});
}
});
mLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(CustomerLoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()){
Toast.makeText(CustomerLoginActivity.this, "sign in error", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(firebaseAuthListener);
}
#Override
protected void onStop() {
super.onStop();
mAuth.removeAuthStateListener(firebaseAuthListener);
}
}
driver login activity
public class DriverLoginActivity extends AppCompatActivity {
private EditText mEmail, mPassword;
private Button mLogin, mRegistration;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener firebaseAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_driver_login);
mAuth = FirebaseAuth.getInstance();
firebaseAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user!=null){
Intent intent = new Intent(DriverLoginActivity.this, DriverMapActivity.class);
startActivity(intent);
finish();
return;
}
}
};
mEmail = (EditText) findViewById(R.id.email);
mPassword = (EditText) findViewById(R.id.password);
mLogin = (Button) findViewById(R.id.login);
mRegistration = (Button) findViewById(R.id.registration);
mRegistration.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(DriverLoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()){
Toast.makeText(DriverLoginActivity.this, "sign up error", Toast.LENGTH_SHORT).show();
}else{
String user_id = mAuth.getCurrentUser().getUid();
DatabaseReference current_user_db = FirebaseDatabase.getInstance().getReference().child("Users").child("Drivers").child(user_id).child("name");
current_user_db.setValue(email);
}
}
});
}
});
mLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(DriverLoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(!task.isSuccessful()){
Toast.makeText(DriverLoginActivity.this, "sign in error", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(firebaseAuthListener);
}
#Override
protected void onStop() {
super.onStop();
mAuth.removeAuthStateListener(firebaseAuthListener);
}
}
My database rules
Firebase authentication doesn't differentiate between different "types" of users, like you're trying to do. You'll have to implement some custom logic of your own in your app(s) to handle these situations. The base signInWithEmailAndPassword() method will always work if you provide it correct credentials... so what you need to do is in your app code, BEFORE you call the signInWithEmailAndPassword() method, check to see if the provided username is "allowed" to use this version of the app...
So as soon as you get their username, before calling that signIn method, make a query to the database to determine whether that username belongs to a "customer" or a "driver". I assume you have something like a /users node in your database - if you don't, you'll need to create one, there's no way around it. If you're not sure how to query the database, use the addListenerForSingleValueEvent() method... check out the official docs for examples/syntax.
Once you've determined whether the username is for a customer vs a driver... you will need to implement logic to decide whether they are allowed to proceed to the signIn method.
If they are a "customer" and this is the "customer" app, then allow the code to proceed to the signIn method... but if the username comes back as a "driver" then stop the code and display an error to the user.
Similarly for the "driver" app, if the username comes back as being for a "driver" then allow the code to proceed to the signIn method... but if it comes back as a "customer" then stop the code and display an error to the user.

MainActivty should lead to LoginActivity but skips it. Leads to MapActivity that should only be visible after login

I seem to have altered something in my code and I can't figure out what it is I need to revert.
I'm building an app that will have a MainActivity that will lead to a loginActivity. However, when the login button is pressed the app is now skipping that and going to a MapActivity that should only be visible to logged in users.
I've checked my MainActivity code and I don't think the problem is there, I think it's the LoginActivity code:
public class ResponderLoginActivity extends AppCompatActivity {
private EditText mEmail, mPassword;
private Button mLogin, mRegistration;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener firebaseAuthListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_responder_login);
mAuth = FirebaseAuth.getInstance();
firebaseAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
Intent intent = new Intent(ResponderLoginActivity.this, ResponderMapActivity.class);
startActivity(intent);
finish();
return;
}
}
};
mEmail = (EditText) findViewById(R.id.email);
mPassword = (EditText) findViewById(R.id.password);
mLogin = (Button) findViewById(R.id.login);
mRegistration = (Button) findViewById(R.id.registration);
mRegistration.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(ResponderLoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(ResponderLoginActivity.this, "sign up error", Toast.LENGTH_SHORT).show();
} else {
String user_id = mAuth.getCurrentUser().getUid();
DatabaseReference current_user_db = FirebaseDatabase.getInstance().getReference().child("Users").child("Responders").child(user_id);
current_user_db.setValue(true);
}
}
});
}
});
mLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(ResponderLoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
Toast.makeText(ResponderLoginActivity.this, "Sign in error", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
#Override
protected void onStart() {
super.onStart();
mAuth.addAuthStateListener(firebaseAuthListener);
}
#Override
protected void onStop() {
super.onStop();
mAuth.removeAuthStateListener(firebaseAuthListener);
}
}

Firebase signout not performed

I am using Firebase Authentification for an Application and I got stuck with an issue.
Firebase FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password) method signs in the user automatically. But I don't want this because I need email verification before log in.
So I implemented a signout when I finish my signup flow. You can find my code below.
My problem is that when I get back to LoginActivity from SignUpActivity, the FirebaseAuthStateListener from LoginActivity detects a user and goes to MainActivity which is something I don't want.
Has anyone ever run through the same issue ?
I am currently using a flag to fix this, but I don't like it at all. I don't get why FirebaseAuth returns a non-null user after I have signed out.
Thanks in advance,
Adrien.
LoginActivity.java
public class LoginActivity extends AppCompatActivity {
// Firebase stuff
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
// Facebook stuff
private CallbackManager mCallbackManager;
private Button mLoginButton;
// Views stuff
private LoginButton mLoginFbButton;
private EditText mEmailTextField;
private EditText mPasswordTextField;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
viewsSetup();
firebaseSetUp();
}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onPause() {
super.onPause();
if(mAuthListener != null)mAuth.removeAuthStateListener(mAuthListener);
}
#Override
public void onResume() {
super.onResume();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SIGNUP) {
if (resultCode == RESULT_OK) {
Toast.makeText(getBaseContext(), getString(R.string.you_can_login), Toast.LENGTH_LONG).show();
}
}
onResume();
super.onActivityResult(requestCode, resultCode, data);
mCallbackManager.onActivityResult(requestCode, resultCode, data);
}
private void firebaseSetUp() {
mAuth = FirebaseAuth.getInstance();
// Will be notified on login success
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null && !mFromSignup) {
// Login success is handled here and should not be handled anywhere else.
mLoginButton.setEnabled(true);
// Stop the progress dialog
mProgressDialog.dismiss();
toMainActivity();
}
}
};
}
private void signIn(AuthCredential credential) {
// pops up the progress dialog
mProgressDialog = ProgressDialog.show(this, getString(R.string.signing_in), null, true);
// Will be notified when sign in request finish
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
// Do not handle authentification success here, on complete
// this will notify the Authentification Listener
if (!task.isSuccessful()) {
Log.w(TAG, "signInWithCredential", task.getException());
Toast.makeText(LoginActivity.this, getString(R.string.login_failed_message),
Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
mLoginButton.setEnabled(true);
}
}
});
}
private void viewsSetup() {
mEmailTextField = (EditText) findViewById(R.id.email);
mPasswordTextField = (EditText) findViewById(R.id.password);
mLoginButton = (Button) findViewById(R.id.login_button);
mLoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loginButtonPressed();
}
});
TextView mSignUp = (TextView) findViewById(R.id.create_an_account);
mSignUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), SignUpActivity.class);
onPause();
startActivityForResult(intent, REQUEST_SIGNUP);
}
});
mProgressDialog = new ProgressDialog(this);
}
private void loginButtonPressed() {
Log.d(TAG, "Login");
if (!textFieldsFormatValid()) {
Toast.makeText(LoginActivity.this, getString(R.string.check_text_fields),
Toast.LENGTH_SHORT).show();
return;
}
View view = getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
mLoginButton.setEnabled(false);
String email = mEmailTextField.getText().toString();
String password = mPasswordTextField.getText().toString();
signIn();
}
private boolean textFieldsFormatValid() {
boolean valid = true;
String email = mEmailTextField.getText().toString();
String password = mPasswordTextField.getText().toString();
if (email.isEmpty() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
mEmailTextField.setError(getString(R.string.ask_valid_email));
valid = false;
} else {
mEmailTextField.setError(null);
}
if (password.isEmpty()) {
mPasswordTextField.setError(getString(R.string.required_field_msg));
valid = false;
} else {
mPasswordTextField.setError(null);
}
return valid;
}
private void toMainActivity() {
// Go to main activity
startActivity(new Intent(LoginActivity.this, MainActivity.class));
// Destroy activity to free memory we won't need it anymore until logout
finish();
}
}
SignUpActivity.java
public class SignUpActivity extends AppCompatActivity {
// Used to determine when user finished signing up
private boolean mFinished = false;
// Firebase stuff
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
// Views stuff
private EditText mEmail;
private EditText mPassword;
private EditText mPasswordConfirm;
private EditText mFullname;
private Button mSignUpButton;
private ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
firebaseSetup();
viewsSetup();
}
#Override
public void onDestroy() {
super.onStop();
if(mAuthListener != null) mAuth.removeAuthStateListener(mAuthListener);
}
private void signUp() {
mProgressDialog = ProgressDialog.show(this, getString(R.string.signing_up), null, true);
if (!textFieldsFormatValid()) {
Toast.makeText(getBaseContext(), getString(R.string.check_text_fields), Toast.LENGTH_LONG).show();
return;
}
mSignUpButton.setEnabled(false);
final String email = mEmail.getText().toString();
final String password = mPassword.getText().toString();
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
// Do not handle authentification success here, on complete
// this will notify the Authentification Listener
if(!task.isSuccessful()) {
Toast.makeText(getBaseContext(), getString(R.string.signup_fail), Toast.LENGTH_LONG).show();
mSignUpButton.setEnabled(true);
mProgressDialog.dismiss();
} else {
mFinished = true;
}
}
});
}
private void firebaseSetup() {
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull final FirebaseAuth firebaseAuth) {
final FirebaseUser user = firebaseAuth.getCurrentUser();
if(user != null && !mFinished) {
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(mFullname.getText().toString())
.build();
user.updateProfile(profileUpdates).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
firebaseAuth.signOut();
}
});
} else if (mFinished){
// Wait for logout here
firebaseAuth.removeAuthStateListener(this);
mSignUpButton.setEnabled(true);
mProgressDialog.dismiss();
setResult(RESULT_OK, null);
finish();
}
}
};
mAuth.addAuthStateListener(mAuthListener);
}
private void viewsSetup() {
mEmail = (EditText) findViewById(R.id.email);
mPassword = (EditText) findViewById(R.id.password);
mPasswordConfirm = (EditText) findViewById(R.id.password_confirm);
mFullname = (EditText) findViewById(R.id.full_name);
mSignUpButton = (Button) findViewById(R.id.signup_button);
TextView mLoginLink = (TextView) findViewById(R.id.to_login);
mSignUpButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
signUpButtonPressed();
}
});
mLoginLink.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
mProgressDialog = new ProgressDialog(this);
}
private void signUpButtonPressed() {
View view = getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
if(!textFieldsFormatValid()) {
Toast.makeText(this, R.string.toast_signup_failed, Toast.LENGTH_SHORT);
return;
}
signUp();
}
private boolean textFieldsFormatValid() {
boolean valid = true;
String email = mEmail.getText().toString();
String password = mPassword.getText().toString();
String password2 = mPasswordConfirm.getText().toString();
if (email.isEmpty() || !Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
mEmail.setError(getString(R.string.ask_valid_email));
valid = false;
} else {
mEmail.setError(null);
}
if (password.isEmpty() || password.length() < 6 || password.length() > 10) {
mPassword.setError(getString(R.string.password_err_msg));
valid = false;
} else {
mPassword.setError(null);
}
if (password2.isEmpty() || password2.length() < 6 || password2.length() > 10) {
mPasswordConfirm.setError(getString(R.string.password_err_msg));
valid = false;
} else if (!password2.equals(password)) {
mPasswordConfirm.setError(getString(R.string.match_passwords));
valid = false;
} else {
mPasswordConfirm.setError(null);
}
return valid;
}
}
In case someone faces the same problem once, here is how I solved it:
The problem came from the fact I was calling firebaseAuth.signOut() from an asynchronous task (at the completion of user.updateProfile(profile)). And I made an error writing else if(mFinished) and not checking if user == null.
Which led to some cases where I came back to LoginActivity without being signed out.

Categories

Resources