CodeReview of a Firebase Login/Registration ProcessMax heap in JavaRegistration and Login System for ApplicationLogin/registration part of an Android applicationImplementation of stackUser registration factory for AngularJS + Firebase appLogging in to Android application using FirebaseAngular Guards - Firebase loggedInAndVerifiedMake methods shorter when parsing Firebase dataFirebase Plotter for IonicAndroid app to take a photos and show them in a gallery

Are hand made posters acceptable in Academia?

UK Tourist Visa- Enquiry

Have any astronauts/cosmonauts died in space?

TDE Master Key Rotation

Single word to change groups

Why doesn't the fusion process of the sun speed up?

is this saw blade faulty?

What is the difference between something being completely legal and being completely decriminalized?

Is there any common country to visit for uk and schengen visa?

When should a starting writer get his own webpage?

Turning a hard to access nut?

What will the Frenchman say?

Hackerrank All Women's Codesprint 2019: Name the Product

Print last inputted byte

DisplayForm problem with pi in FractionBox

Have the tides ever turned twice on any open problem?

Hot air balloons as primitive bombers

Why is participating in the European Parliamentary elections used as a threat?

Weird lines in Microsoft Word

How to balance a monster modification (zombie)?

Determine voltage drop over 10G resistors with cheap multimeter

Why is indicated airspeed rather than ground speed used during the takeoff roll?

Do I need to convey a moral for each of my blog post?

Do native speakers use "ultima" and "proxima" frequently in spoken English?



CodeReview of a Firebase Login/Registration Process


Max heap in JavaRegistration and Login System for ApplicationLogin/registration part of an Android applicationImplementation of stackUser registration factory for AngularJS + Firebase appLogging in to Android application using FirebaseAngular Guards - Firebase loggedInAndVerifiedMake methods shorter when parsing Firebase dataFirebase Plotter for IonicAndroid app to take a photos and show them in a gallery













0












$begingroup$


I am developing another bigger project, I want to try a simple DatingApp and currently I try to develope a Login and Registration Form. There is no special register / login button, the code will later decide wether email is registered (-> login) or not (-> register). But even though it's working I am not sure if I make things to complex:


First I want so show a very simple overview of the logic I try to develope:



enter image description here





The App launches with the LogoActivity as a simple SplashScreen. In here the Activity decides which Activity and Fragment is about to be displayed next. It has a sharedElementTransition connected to the AuthOptionActivity.


The AuthOptionActivity only contains the Logo and a fragment Container.

Depending on the AuthStatus it will show the AuthOptionFragment, containing a Layout with two Buttons. Here you can decide which way you want to use for your registration.


In case there is for example an email-registered user but he is not verified yet the AuthOptionActivity will show the MailAuthFragment instead of the AuthOptionFragment.


The MailAuthOptionFragment itselfs contains another two ChildFragments.

The EnterMailSubFragment contains two EditText-Views and the ConfirmMailSubFragment is just a Text containing the Email Adress and a clickable resend textview (not implemented yet).


The code so far implemented is working but it is not that clear as I want it to be.

Logo Activity



public class LogoActivity extends AppCompatActivity {

private ImageView mLogo;
private Handler mHandler;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logo);
this.init();


private void init()
mLogo = findViewById(R.id.activity_logo_logo);
AuthHandler.performStartUpCheck(new AuthHandler.StartupAuthStatus()
@Override
public void noUser()
Toast.makeText(LogoActivity.this, "No User", Toast.LENGTH_SHORT).show();
performSharedElementTransactionToAuthOption();


@Override
public void onError(String e)
Toast.makeText(LogoActivity.this, e, Toast.LENGTH_SHORT).show();
performSharedElementTransactionToAuthOption();


@Override
public void onPhone()
Toast.makeText(LogoActivity.this, "Phone", Toast.LENGTH_SHORT).show();
//direct to loadingActivity


@Override
public void onEmail(boolean isVerified)
Toast.makeText(LogoActivity.this, "Email" + String.valueOf(isVerified), Toast.LENGTH_SHORT).show();
if(isVerified)
//direct to LoadingActivity
else
performSharedElementTransactionToAuthOption();


);
//this.performSharedElementTransaction();


private void performSharedElementTransactionToAuthOption()
//check for auth and proceed to Loading
Intent pIntent = new Intent(LogoActivity.this, AuthOptionActivity.class);
ActivityOptions mOptions = ActivityOptions.makeSceneTransitionAnimation(LogoActivity.this, mLogo, mLogo.getTransitionName());
startActivity(pIntent, mOptions.toBundle());



private void performTransactionToLoadingScreen()
/**dummy**/


@Override
protected void onStop()
//Call finish here to avoid flickering
this.finish();
super.onStop();





Nothing so special here, I am quite happy with that class. Disregard some comments, they are just for me as a reminder.


AuthHandler



public class AuthHandler 

public interface StartupAuthStatus
void noUser();
void onError(String e);
void onPhone();
void onEmail(boolean isVerified);


public interface SignInStatus
void onEmail(boolean isVerified);


private FirebaseAuth mAuth;
private FirebaseFirestore mFirestore;

/**STARTUP PROCEDURE**/

public static void performStartUpCheck(final StartupAuthStatus mCallback)
final FirebaseAuth mAuth = FirebaseAuth.getInstance();
checkStartupAuthStatus(mAuth, mCallback);



private static void checkStartupAuthStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
mAuth = FirebaseAuth.getInstance();
checkForCurrentUser(mAuth,mCallback);


private static void checkForCurrentUser(FirebaseAuth mAuth, StartupAuthStatus mCallback)
if(mAuth.getCurrentUser()!=null)
checkRegistrationMethod(mAuth, mCallback);
else
mCallback.noUser();



private static void checkRegistrationMethod(final FirebaseAuth mAuth, final StartupAuthStatus mCallback)
if(mAuth.getUid() == null)
mCallback.onError("NullPointerInUID");
return;

FirebaseFirestore.getInstance().collection("Registration").document(mAuth.getUid()).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task)
if(task.getResult() != null && task.getResult().exists())
Map<String, Object> mData = task.getResult().getData();
String mRegistrationForm = (String) mData.get("reg");
if(mRegistrationForm.equals("mail"))
checkMailVerificationStatus(mAuth, mCallback);
else if(mRegistrationForm.equals("phone"))
mCallback.onPhone();



).addOnFailureListener(new OnFailureListener()
@Override
public void onFailure(@NonNull Exception e)
mCallback.onError(e.getMessage());
mAuth.signOut();

);


private static void checkMailVerificationStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
if(mAuth.getCurrentUser().isEmailVerified())
mCallback.onEmail(true);
else
mCallback.onEmail(false);



/**LOGIN PROCEDURE**/

public static void enterUserWithEmailAndPassword(String mEmail, String mPassword)
FirebaseAuth mAuth = FirebaseAuth.getInstance();
createUserWithEmailAndPassword(mAuth, mEmail, mPassword);


private static void createUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



private static void signUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



private static void sendVerificationEmail(FirebaseAuth mAuth)



private static void setupRegistrationModel(String mModelType)



/**DELETE PROCEDURE**/





This class is made to "outsource" the code mess. Here I am not sure if it's a common or even usefull way to handle this. The Database contains Users (with a lot of Data later) and a Pool of Registrations, here I only store the choosen registration form (field reg(String): "phone" or "mail").

I need to seperate it somehow as the email-registrated-user needs to verify the email.


AuthOptionActivity



public class AuthOptionActivity extends AppCompatActivity 

@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authoption);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
getWindow().setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.move));

this.checkAuthStatus();


@Override
public void onBackPressed()
findViewById(R.id.activity_authoption_logo).setTransitionName(null);
super.onBackPressed();
/** Problem occured: SharedViewElement will be visible after App was closed.
* Reason: The View will try to perform the ExitTransition
* Solution 1: Delete super.onBackPressed(); and override with finish();
* Solution 2: Set Transitionname to Null**/


/**The SlideEnter Transition is variable, on First Startup we want a smooth slide in,
* for phoneauth we want a Left-Side Slide and for Email a Right-Side Slide.
* The Exit Animation is always slide-out-bottom-smooth.
* The Reenter Animation is always slide-in-bottom-smooth and due to overlapping
* the ExitTransition of the View before BackPress will be hidden and is always 0**/

private void performFragmentTransaction(Fragment mFragment, String mTag, Boolean mAddToBackStack, int mEnterTransition)
FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();
mFragmentTransaction.setCustomAnimations(mEnterTransition, 0, R.anim.slide_in_bottom_smooth, 0);
if(mAddToBackStack)
mFragmentTransaction.addToBackStack(mTag);

mFragmentTransaction.replace(R.id.activity_authoption_container, mFragment, mTag);
mFragmentTransaction.commit();



/**Check Auth Status: if CurrentUser != null but not Email verified -> Show MailAuth**/
private void checkAuthStatus()
if(FirebaseAuth.getInstance().getCurrentUser()!=null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
//very bad way to force a backstack, still looking for a solution
this.showAuthOptionFragment();
this.showMailAuth();
else
this.showAuthOptionFragment();



/**Handle Fragment Transaction including Listener**/
private void showAuthOptionFragment()
this.performFragmentTransaction(AuthOptionFragment.newInstance(new AuthOptionFragment.ClickListener()
@Override
public void onMail()
showMailAuth();


@Override
public void onPhone()
showPhoneAuth();

), "AuthOption", false, R.anim.slide_in_bottom);


private void showPhoneAuth()
this.performFragmentTransaction(_PhoneAuthFragment.newInstance(new _PhoneAuthFragment.AuthStatusListener()
@Override
public void onCancel()
//PhoneAuthFragment contains a "back" Button it will fire "onCancel()"
onBackPressed();


@Override
public void onSuccess()
//show LoadingScreen

), "PhoneAuth", true, R.anim.slide_in_left_smooth);


private void showMailAuth()
this.performFragmentTransaction(_MailAuthFragment.newInstance(new _MailAuthFragment.AuthStatusListener()
@Override
public void onCancel()
//MailAuthFragment contains a "back" Button it will fire "onCancel()"
onBackPressed();


@Override
public void onSuccess()
//show LoadingScreen

), "MailAuth", true, R.anim.slide_in_right_smooth);






For this activity I have some questions:

1. I am checking the Auth Status & email again to decide which fragment to show. It's easy and simple, but repetitive (it will occur again in MailAuthFragment). Is it a common way to repetitive use FirebaseAuth instances?


2. I have seen a couple of fragment -> activity communication solutions using onAttach etc. Is my solution to pass a CustomListener(interface) in the newInstance method okay? Is there any bug that could occur using it that way?

I pretty much like it as it makes the handling easier.



MailAuthOptionFragment



public class _MailAuthFragment extends Fragment 

public interface AuthStatusListener
void onCancel();
void onSuccess();


private AuthStatusListener mCallback;
private String mActiveWindow;
private CheckCancelButton mCheckCancelButton;

private String mEmail;
private String mPassword;

@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);


@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View mView = inflater.inflate(R.layout.fragment_mailauth, container, false);
this.checkAuthStatus();
this.initButton(mView);
return mView;


/**PUBLIC METHODS**/

/**Set the Fragment Listener for AuthOptionActivity**/
public void setListener(AuthStatusListener mCallback)
this.mCallback = mCallback;


/**Replaces hard coded Instances as Listener will be passed directly**/
public static _MailAuthFragment newInstance(AuthStatusListener mCallback)
_MailAuthFragment mFragment = new _MailAuthFragment();
mFragment.setListener(mCallback);
return mFragment;


/**PRIVATE METHODS**/

/**Check AuthStatus, if CurrentUser!=null but not verified -> Show VerificationScreen**/
private void checkAuthStatus()
if(FirebaseAuth.getInstance().getCurrentUser() != null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
this.showConfirmEmailSubFragment(R.anim.slide_in_right_smooth);
else
this.showEnterEmailSubFragment(R.anim.slide_in_right_smooth);



/**Handle Registration Process Fragments**/
private void performFragmentTransaction(Fragment mFragment, String mTag, int mEnterAnim)
mActiveWindow = mTag;
FragmentTransaction mFragmentTransaction = getChildFragmentManager().beginTransaction();
mFragmentTransaction.setCustomAnimations(mEnterAnim, 0);
mFragmentTransaction.replace(R.id.fragment_mailauth_container, mFragment, mTag);
mFragmentTransaction.commit();


/**MailAuth receives any valid TextChange from SubFragment**/
private void showEnterEmailSubFragment(int mEnterAnim)

this.performFragmentTransaction(EnterMailSubFragment.newInstance(new EnterMailSubFragment.EnterMailListener()
@Override
public void onEmailChanged(String mEmail)
_MailAuthFragment.this.mEmail = mEmail;


@Override
public void onPasswordChanged(String mPassword)
_MailAuthFragment.this.mPassword = mPassword;

), "EnterMail", mEnterAnim);



/**MailAuth receives resend VerificationEmailRequest from SubFragment**/
private void showConfirmEmailSubFragment(int mEnterAnim)
this.performFragmentTransaction(new ConfirmMailSubFragment(), "ConfirmMail", R.anim.slide_in_right_smooth);


private void initButton(final View mView)
/**Custom Button using AfterEffects, Bodymovin and LottieView, contains some commands like "transform to tick"**/
mCheckCancelButton = new CheckCancelButton((LottieAnimationView)mView.findViewById(R.id.fragment_mailauth_nextBtn));
mCheckCancelButton.setCustomClickListener(new CheckCancelButton.CheckCancelButtonClickListener()
@Override
public void onClick()
switch(mActiveWindow)
case "EnterMail":
// the received Email and Password will be passed to AuthHandlerClass - not implemented yet
break;
case "ConfirmMail":
// the AuthHandler will reloard the currentUser and check for email verification Status - not implemented yet
break;


);





Checking AuthStatus again and choosing wether to show the EnterEmailSubFragment or the ConfirmEmailSubFragment. This class contains a button handling both SubFragment pages. This leads to that switch-case method. Not sure if that is a proper way.



EnterMailSubFragment



public class EnterMailSubFragment extends Fragment 

public interface EnterMailListener
void onEmailChanged(String mEmail);
void onPasswordChanged(String mPassword);


private EnterMailListener mCallback;
private EditText mEmail, mPassword;
private ImageView mEmailWarning, mPasswordWarning;

@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View mView = inflater.inflate(R.layout.subfragment_mailauth, container, false);
this.initUiWidgets(mView);
this.initEditText(mView);
return mView;


public void setEnterMailListener(EnterMailListener mMailListener)
this.mCallback = mMailListener;


public static EnterMailSubFragment newInstance(EnterMailListener mMailListener)
EnterMailSubFragment mFragment = new EnterMailSubFragment();
mFragment.setEnterMailListener(mMailListener);
return mFragment;


private void initUiWidgets(View mView)
mEmail = mView.findViewById(R.id.subfragment_mailauth_email_ET);
mPassword = mView.findViewById(R.id.subfragment_mailauth_password_et);
mEmailWarning = mView.findViewById(R.id.subfragment_mailauth_email_warning);
mPasswordWarning = mView.findViewById(R.id.subfragment_mailauth_password_warning);


/**Any Valid Entry will be passed to MailFragment**/

private void initEditText(final View mView)
mEmail.addTextChangedListener(new TextWatcher()
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)



@Override
public void onTextChanged(CharSequence s, int start, int before, int count)



@Override
public void afterTextChanged(Editable s)
if(mEmail.getText() != null && Patterns.EMAIL_ADDRESS.matcher(mEmail.getText().toString()).matches())
mEmailWarning.setVisibility(View.GONE);
mCallback.onEmailChanged(mEmail.getText().toString());
else
mEmailWarning.setVisibility(View.VISIBLE);


);

mPassword.addTextChangedListener(new TextWatcher()
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)



@Override
public void onTextChanged(CharSequence s, int start, int before, int count)


@Override
public void afterTextChanged(Editable s)
if(mPassword.getText() != null && mPassword.getText().length() >= 6)
mPasswordWarning.setVisibility(View.GONE);
mCallback.onPasswordChanged(mPassword.getText().toString());
else
mPasswordWarning.setVisibility(View.VISIBLE);


);






The Textwatcher checks every entry and transfers it to the MailAuthFragment as MailAuthFragment handels the button event (this is for design puposes, I want the content to move and the button is meant to stay in its position).



ConfirmMailAuthSubFragment



public class ConfirmMailSubFragment extends Fragment 

public interface ConfirmMailListener
void onResendEmail();


private ConfirmMailListener mCallback;

@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);


@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View mView = inflater.inflate(R.layout.subfragment_confirmmail, container, false);

return mView;


public void setConfirmMailListener(ConfirmMailListener mCallback)
this.mCallback = mCallback;


public static ConfirmMailSubFragment newInstance(ConfirmMailListener mCallback)
ConfirmMailSubFragment mFragment = new ConfirmMailSubFragment();
mFragment.setConfirmMailListener(mCallback);
return mFragment;





Nothing special here yet. It will handle the Button Event "Resend Verification Mail" and transfer it to MailAuthFragment.



I know it's a very early stage of my code but as beautiful as it looks with that slide in animations I am not sure if I am running in the wrong direction or making stuff unnecessary complex.









share









$endgroup$
















    0












    $begingroup$


    I am developing another bigger project, I want to try a simple DatingApp and currently I try to develope a Login and Registration Form. There is no special register / login button, the code will later decide wether email is registered (-> login) or not (-> register). But even though it's working I am not sure if I make things to complex:


    First I want so show a very simple overview of the logic I try to develope:



    enter image description here





    The App launches with the LogoActivity as a simple SplashScreen. In here the Activity decides which Activity and Fragment is about to be displayed next. It has a sharedElementTransition connected to the AuthOptionActivity.


    The AuthOptionActivity only contains the Logo and a fragment Container.

    Depending on the AuthStatus it will show the AuthOptionFragment, containing a Layout with two Buttons. Here you can decide which way you want to use for your registration.


    In case there is for example an email-registered user but he is not verified yet the AuthOptionActivity will show the MailAuthFragment instead of the AuthOptionFragment.


    The MailAuthOptionFragment itselfs contains another two ChildFragments.

    The EnterMailSubFragment contains two EditText-Views and the ConfirmMailSubFragment is just a Text containing the Email Adress and a clickable resend textview (not implemented yet).


    The code so far implemented is working but it is not that clear as I want it to be.

    Logo Activity



    public class LogoActivity extends AppCompatActivity {

    private ImageView mLogo;
    private Handler mHandler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_logo);
    this.init();


    private void init()
    mLogo = findViewById(R.id.activity_logo_logo);
    AuthHandler.performStartUpCheck(new AuthHandler.StartupAuthStatus()
    @Override
    public void noUser()
    Toast.makeText(LogoActivity.this, "No User", Toast.LENGTH_SHORT).show();
    performSharedElementTransactionToAuthOption();


    @Override
    public void onError(String e)
    Toast.makeText(LogoActivity.this, e, Toast.LENGTH_SHORT).show();
    performSharedElementTransactionToAuthOption();


    @Override
    public void onPhone()
    Toast.makeText(LogoActivity.this, "Phone", Toast.LENGTH_SHORT).show();
    //direct to loadingActivity


    @Override
    public void onEmail(boolean isVerified)
    Toast.makeText(LogoActivity.this, "Email" + String.valueOf(isVerified), Toast.LENGTH_SHORT).show();
    if(isVerified)
    //direct to LoadingActivity
    else
    performSharedElementTransactionToAuthOption();


    );
    //this.performSharedElementTransaction();


    private void performSharedElementTransactionToAuthOption()
    //check for auth and proceed to Loading
    Intent pIntent = new Intent(LogoActivity.this, AuthOptionActivity.class);
    ActivityOptions mOptions = ActivityOptions.makeSceneTransitionAnimation(LogoActivity.this, mLogo, mLogo.getTransitionName());
    startActivity(pIntent, mOptions.toBundle());



    private void performTransactionToLoadingScreen()
    /**dummy**/


    @Override
    protected void onStop()
    //Call finish here to avoid flickering
    this.finish();
    super.onStop();





    Nothing so special here, I am quite happy with that class. Disregard some comments, they are just for me as a reminder.


    AuthHandler



    public class AuthHandler 

    public interface StartupAuthStatus
    void noUser();
    void onError(String e);
    void onPhone();
    void onEmail(boolean isVerified);


    public interface SignInStatus
    void onEmail(boolean isVerified);


    private FirebaseAuth mAuth;
    private FirebaseFirestore mFirestore;

    /**STARTUP PROCEDURE**/

    public static void performStartUpCheck(final StartupAuthStatus mCallback)
    final FirebaseAuth mAuth = FirebaseAuth.getInstance();
    checkStartupAuthStatus(mAuth, mCallback);



    private static void checkStartupAuthStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
    mAuth = FirebaseAuth.getInstance();
    checkForCurrentUser(mAuth,mCallback);


    private static void checkForCurrentUser(FirebaseAuth mAuth, StartupAuthStatus mCallback)
    if(mAuth.getCurrentUser()!=null)
    checkRegistrationMethod(mAuth, mCallback);
    else
    mCallback.noUser();



    private static void checkRegistrationMethod(final FirebaseAuth mAuth, final StartupAuthStatus mCallback)
    if(mAuth.getUid() == null)
    mCallback.onError("NullPointerInUID");
    return;

    FirebaseFirestore.getInstance().collection("Registration").document(mAuth.getUid()).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task)
    if(task.getResult() != null && task.getResult().exists())
    Map<String, Object> mData = task.getResult().getData();
    String mRegistrationForm = (String) mData.get("reg");
    if(mRegistrationForm.equals("mail"))
    checkMailVerificationStatus(mAuth, mCallback);
    else if(mRegistrationForm.equals("phone"))
    mCallback.onPhone();



    ).addOnFailureListener(new OnFailureListener()
    @Override
    public void onFailure(@NonNull Exception e)
    mCallback.onError(e.getMessage());
    mAuth.signOut();

    );


    private static void checkMailVerificationStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
    if(mAuth.getCurrentUser().isEmailVerified())
    mCallback.onEmail(true);
    else
    mCallback.onEmail(false);



    /**LOGIN PROCEDURE**/

    public static void enterUserWithEmailAndPassword(String mEmail, String mPassword)
    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    createUserWithEmailAndPassword(mAuth, mEmail, mPassword);


    private static void createUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



    private static void signUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



    private static void sendVerificationEmail(FirebaseAuth mAuth)



    private static void setupRegistrationModel(String mModelType)



    /**DELETE PROCEDURE**/





    This class is made to "outsource" the code mess. Here I am not sure if it's a common or even usefull way to handle this. The Database contains Users (with a lot of Data later) and a Pool of Registrations, here I only store the choosen registration form (field reg(String): "phone" or "mail").

    I need to seperate it somehow as the email-registrated-user needs to verify the email.


    AuthOptionActivity



    public class AuthOptionActivity extends AppCompatActivity 

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_authoption);
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    getWindow().setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.move));

    this.checkAuthStatus();


    @Override
    public void onBackPressed()
    findViewById(R.id.activity_authoption_logo).setTransitionName(null);
    super.onBackPressed();
    /** Problem occured: SharedViewElement will be visible after App was closed.
    * Reason: The View will try to perform the ExitTransition
    * Solution 1: Delete super.onBackPressed(); and override with finish();
    * Solution 2: Set Transitionname to Null**/


    /**The SlideEnter Transition is variable, on First Startup we want a smooth slide in,
    * for phoneauth we want a Left-Side Slide and for Email a Right-Side Slide.
    * The Exit Animation is always slide-out-bottom-smooth.
    * The Reenter Animation is always slide-in-bottom-smooth and due to overlapping
    * the ExitTransition of the View before BackPress will be hidden and is always 0**/

    private void performFragmentTransaction(Fragment mFragment, String mTag, Boolean mAddToBackStack, int mEnterTransition)
    FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();
    mFragmentTransaction.setCustomAnimations(mEnterTransition, 0, R.anim.slide_in_bottom_smooth, 0);
    if(mAddToBackStack)
    mFragmentTransaction.addToBackStack(mTag);

    mFragmentTransaction.replace(R.id.activity_authoption_container, mFragment, mTag);
    mFragmentTransaction.commit();



    /**Check Auth Status: if CurrentUser != null but not Email verified -> Show MailAuth**/
    private void checkAuthStatus()
    if(FirebaseAuth.getInstance().getCurrentUser()!=null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
    //very bad way to force a backstack, still looking for a solution
    this.showAuthOptionFragment();
    this.showMailAuth();
    else
    this.showAuthOptionFragment();



    /**Handle Fragment Transaction including Listener**/
    private void showAuthOptionFragment()
    this.performFragmentTransaction(AuthOptionFragment.newInstance(new AuthOptionFragment.ClickListener()
    @Override
    public void onMail()
    showMailAuth();


    @Override
    public void onPhone()
    showPhoneAuth();

    ), "AuthOption", false, R.anim.slide_in_bottom);


    private void showPhoneAuth()
    this.performFragmentTransaction(_PhoneAuthFragment.newInstance(new _PhoneAuthFragment.AuthStatusListener()
    @Override
    public void onCancel()
    //PhoneAuthFragment contains a "back" Button it will fire "onCancel()"
    onBackPressed();


    @Override
    public void onSuccess()
    //show LoadingScreen

    ), "PhoneAuth", true, R.anim.slide_in_left_smooth);


    private void showMailAuth()
    this.performFragmentTransaction(_MailAuthFragment.newInstance(new _MailAuthFragment.AuthStatusListener()
    @Override
    public void onCancel()
    //MailAuthFragment contains a "back" Button it will fire "onCancel()"
    onBackPressed();


    @Override
    public void onSuccess()
    //show LoadingScreen

    ), "MailAuth", true, R.anim.slide_in_right_smooth);






    For this activity I have some questions:

    1. I am checking the Auth Status & email again to decide which fragment to show. It's easy and simple, but repetitive (it will occur again in MailAuthFragment). Is it a common way to repetitive use FirebaseAuth instances?


    2. I have seen a couple of fragment -> activity communication solutions using onAttach etc. Is my solution to pass a CustomListener(interface) in the newInstance method okay? Is there any bug that could occur using it that way?

    I pretty much like it as it makes the handling easier.



    MailAuthOptionFragment



    public class _MailAuthFragment extends Fragment 

    public interface AuthStatusListener
    void onCancel();
    void onSuccess();


    private AuthStatusListener mCallback;
    private String mActiveWindow;
    private CheckCancelButton mCheckCancelButton;

    private String mEmail;
    private String mPassword;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    super.onCreate(savedInstanceState);


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    View mView = inflater.inflate(R.layout.fragment_mailauth, container, false);
    this.checkAuthStatus();
    this.initButton(mView);
    return mView;


    /**PUBLIC METHODS**/

    /**Set the Fragment Listener for AuthOptionActivity**/
    public void setListener(AuthStatusListener mCallback)
    this.mCallback = mCallback;


    /**Replaces hard coded Instances as Listener will be passed directly**/
    public static _MailAuthFragment newInstance(AuthStatusListener mCallback)
    _MailAuthFragment mFragment = new _MailAuthFragment();
    mFragment.setListener(mCallback);
    return mFragment;


    /**PRIVATE METHODS**/

    /**Check AuthStatus, if CurrentUser!=null but not verified -> Show VerificationScreen**/
    private void checkAuthStatus()
    if(FirebaseAuth.getInstance().getCurrentUser() != null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
    this.showConfirmEmailSubFragment(R.anim.slide_in_right_smooth);
    else
    this.showEnterEmailSubFragment(R.anim.slide_in_right_smooth);



    /**Handle Registration Process Fragments**/
    private void performFragmentTransaction(Fragment mFragment, String mTag, int mEnterAnim)
    mActiveWindow = mTag;
    FragmentTransaction mFragmentTransaction = getChildFragmentManager().beginTransaction();
    mFragmentTransaction.setCustomAnimations(mEnterAnim, 0);
    mFragmentTransaction.replace(R.id.fragment_mailauth_container, mFragment, mTag);
    mFragmentTransaction.commit();


    /**MailAuth receives any valid TextChange from SubFragment**/
    private void showEnterEmailSubFragment(int mEnterAnim)

    this.performFragmentTransaction(EnterMailSubFragment.newInstance(new EnterMailSubFragment.EnterMailListener()
    @Override
    public void onEmailChanged(String mEmail)
    _MailAuthFragment.this.mEmail = mEmail;


    @Override
    public void onPasswordChanged(String mPassword)
    _MailAuthFragment.this.mPassword = mPassword;

    ), "EnterMail", mEnterAnim);



    /**MailAuth receives resend VerificationEmailRequest from SubFragment**/
    private void showConfirmEmailSubFragment(int mEnterAnim)
    this.performFragmentTransaction(new ConfirmMailSubFragment(), "ConfirmMail", R.anim.slide_in_right_smooth);


    private void initButton(final View mView)
    /**Custom Button using AfterEffects, Bodymovin and LottieView, contains some commands like "transform to tick"**/
    mCheckCancelButton = new CheckCancelButton((LottieAnimationView)mView.findViewById(R.id.fragment_mailauth_nextBtn));
    mCheckCancelButton.setCustomClickListener(new CheckCancelButton.CheckCancelButtonClickListener()
    @Override
    public void onClick()
    switch(mActiveWindow)
    case "EnterMail":
    // the received Email and Password will be passed to AuthHandlerClass - not implemented yet
    break;
    case "ConfirmMail":
    // the AuthHandler will reloard the currentUser and check for email verification Status - not implemented yet
    break;


    );





    Checking AuthStatus again and choosing wether to show the EnterEmailSubFragment or the ConfirmEmailSubFragment. This class contains a button handling both SubFragment pages. This leads to that switch-case method. Not sure if that is a proper way.



    EnterMailSubFragment



    public class EnterMailSubFragment extends Fragment 

    public interface EnterMailListener
    void onEmailChanged(String mEmail);
    void onPasswordChanged(String mPassword);


    private EnterMailListener mCallback;
    private EditText mEmail, mPassword;
    private ImageView mEmailWarning, mPasswordWarning;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    super.onCreate(savedInstanceState);

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    View mView = inflater.inflate(R.layout.subfragment_mailauth, container, false);
    this.initUiWidgets(mView);
    this.initEditText(mView);
    return mView;


    public void setEnterMailListener(EnterMailListener mMailListener)
    this.mCallback = mMailListener;


    public static EnterMailSubFragment newInstance(EnterMailListener mMailListener)
    EnterMailSubFragment mFragment = new EnterMailSubFragment();
    mFragment.setEnterMailListener(mMailListener);
    return mFragment;


    private void initUiWidgets(View mView)
    mEmail = mView.findViewById(R.id.subfragment_mailauth_email_ET);
    mPassword = mView.findViewById(R.id.subfragment_mailauth_password_et);
    mEmailWarning = mView.findViewById(R.id.subfragment_mailauth_email_warning);
    mPasswordWarning = mView.findViewById(R.id.subfragment_mailauth_password_warning);


    /**Any Valid Entry will be passed to MailFragment**/

    private void initEditText(final View mView)
    mEmail.addTextChangedListener(new TextWatcher()
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after)



    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)



    @Override
    public void afterTextChanged(Editable s)
    if(mEmail.getText() != null && Patterns.EMAIL_ADDRESS.matcher(mEmail.getText().toString()).matches())
    mEmailWarning.setVisibility(View.GONE);
    mCallback.onEmailChanged(mEmail.getText().toString());
    else
    mEmailWarning.setVisibility(View.VISIBLE);


    );

    mPassword.addTextChangedListener(new TextWatcher()
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after)



    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)


    @Override
    public void afterTextChanged(Editable s)
    if(mPassword.getText() != null && mPassword.getText().length() >= 6)
    mPasswordWarning.setVisibility(View.GONE);
    mCallback.onPasswordChanged(mPassword.getText().toString());
    else
    mPasswordWarning.setVisibility(View.VISIBLE);


    );






    The Textwatcher checks every entry and transfers it to the MailAuthFragment as MailAuthFragment handels the button event (this is for design puposes, I want the content to move and the button is meant to stay in its position).



    ConfirmMailAuthSubFragment



    public class ConfirmMailSubFragment extends Fragment 

    public interface ConfirmMailListener
    void onResendEmail();


    private ConfirmMailListener mCallback;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    super.onCreate(savedInstanceState);


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    View mView = inflater.inflate(R.layout.subfragment_confirmmail, container, false);

    return mView;


    public void setConfirmMailListener(ConfirmMailListener mCallback)
    this.mCallback = mCallback;


    public static ConfirmMailSubFragment newInstance(ConfirmMailListener mCallback)
    ConfirmMailSubFragment mFragment = new ConfirmMailSubFragment();
    mFragment.setConfirmMailListener(mCallback);
    return mFragment;





    Nothing special here yet. It will handle the Button Event "Resend Verification Mail" and transfer it to MailAuthFragment.



    I know it's a very early stage of my code but as beautiful as it looks with that slide in animations I am not sure if I am running in the wrong direction or making stuff unnecessary complex.









    share









    $endgroup$














      0












      0








      0





      $begingroup$


      I am developing another bigger project, I want to try a simple DatingApp and currently I try to develope a Login and Registration Form. There is no special register / login button, the code will later decide wether email is registered (-> login) or not (-> register). But even though it's working I am not sure if I make things to complex:


      First I want so show a very simple overview of the logic I try to develope:



      enter image description here





      The App launches with the LogoActivity as a simple SplashScreen. In here the Activity decides which Activity and Fragment is about to be displayed next. It has a sharedElementTransition connected to the AuthOptionActivity.


      The AuthOptionActivity only contains the Logo and a fragment Container.

      Depending on the AuthStatus it will show the AuthOptionFragment, containing a Layout with two Buttons. Here you can decide which way you want to use for your registration.


      In case there is for example an email-registered user but he is not verified yet the AuthOptionActivity will show the MailAuthFragment instead of the AuthOptionFragment.


      The MailAuthOptionFragment itselfs contains another two ChildFragments.

      The EnterMailSubFragment contains two EditText-Views and the ConfirmMailSubFragment is just a Text containing the Email Adress and a clickable resend textview (not implemented yet).


      The code so far implemented is working but it is not that clear as I want it to be.

      Logo Activity



      public class LogoActivity extends AppCompatActivity {

      private ImageView mLogo;
      private Handler mHandler;

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_logo);
      this.init();


      private void init()
      mLogo = findViewById(R.id.activity_logo_logo);
      AuthHandler.performStartUpCheck(new AuthHandler.StartupAuthStatus()
      @Override
      public void noUser()
      Toast.makeText(LogoActivity.this, "No User", Toast.LENGTH_SHORT).show();
      performSharedElementTransactionToAuthOption();


      @Override
      public void onError(String e)
      Toast.makeText(LogoActivity.this, e, Toast.LENGTH_SHORT).show();
      performSharedElementTransactionToAuthOption();


      @Override
      public void onPhone()
      Toast.makeText(LogoActivity.this, "Phone", Toast.LENGTH_SHORT).show();
      //direct to loadingActivity


      @Override
      public void onEmail(boolean isVerified)
      Toast.makeText(LogoActivity.this, "Email" + String.valueOf(isVerified), Toast.LENGTH_SHORT).show();
      if(isVerified)
      //direct to LoadingActivity
      else
      performSharedElementTransactionToAuthOption();


      );
      //this.performSharedElementTransaction();


      private void performSharedElementTransactionToAuthOption()
      //check for auth and proceed to Loading
      Intent pIntent = new Intent(LogoActivity.this, AuthOptionActivity.class);
      ActivityOptions mOptions = ActivityOptions.makeSceneTransitionAnimation(LogoActivity.this, mLogo, mLogo.getTransitionName());
      startActivity(pIntent, mOptions.toBundle());



      private void performTransactionToLoadingScreen()
      /**dummy**/


      @Override
      protected void onStop()
      //Call finish here to avoid flickering
      this.finish();
      super.onStop();





      Nothing so special here, I am quite happy with that class. Disregard some comments, they are just for me as a reminder.


      AuthHandler



      public class AuthHandler 

      public interface StartupAuthStatus
      void noUser();
      void onError(String e);
      void onPhone();
      void onEmail(boolean isVerified);


      public interface SignInStatus
      void onEmail(boolean isVerified);


      private FirebaseAuth mAuth;
      private FirebaseFirestore mFirestore;

      /**STARTUP PROCEDURE**/

      public static void performStartUpCheck(final StartupAuthStatus mCallback)
      final FirebaseAuth mAuth = FirebaseAuth.getInstance();
      checkStartupAuthStatus(mAuth, mCallback);



      private static void checkStartupAuthStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
      mAuth = FirebaseAuth.getInstance();
      checkForCurrentUser(mAuth,mCallback);


      private static void checkForCurrentUser(FirebaseAuth mAuth, StartupAuthStatus mCallback)
      if(mAuth.getCurrentUser()!=null)
      checkRegistrationMethod(mAuth, mCallback);
      else
      mCallback.noUser();



      private static void checkRegistrationMethod(final FirebaseAuth mAuth, final StartupAuthStatus mCallback)
      if(mAuth.getUid() == null)
      mCallback.onError("NullPointerInUID");
      return;

      FirebaseFirestore.getInstance().collection("Registration").document(mAuth.getUid()).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
      @Override
      public void onComplete(@NonNull Task<DocumentSnapshot> task)
      if(task.getResult() != null && task.getResult().exists())
      Map<String, Object> mData = task.getResult().getData();
      String mRegistrationForm = (String) mData.get("reg");
      if(mRegistrationForm.equals("mail"))
      checkMailVerificationStatus(mAuth, mCallback);
      else if(mRegistrationForm.equals("phone"))
      mCallback.onPhone();



      ).addOnFailureListener(new OnFailureListener()
      @Override
      public void onFailure(@NonNull Exception e)
      mCallback.onError(e.getMessage());
      mAuth.signOut();

      );


      private static void checkMailVerificationStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
      if(mAuth.getCurrentUser().isEmailVerified())
      mCallback.onEmail(true);
      else
      mCallback.onEmail(false);



      /**LOGIN PROCEDURE**/

      public static void enterUserWithEmailAndPassword(String mEmail, String mPassword)
      FirebaseAuth mAuth = FirebaseAuth.getInstance();
      createUserWithEmailAndPassword(mAuth, mEmail, mPassword);


      private static void createUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



      private static void signUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



      private static void sendVerificationEmail(FirebaseAuth mAuth)



      private static void setupRegistrationModel(String mModelType)



      /**DELETE PROCEDURE**/





      This class is made to "outsource" the code mess. Here I am not sure if it's a common or even usefull way to handle this. The Database contains Users (with a lot of Data later) and a Pool of Registrations, here I only store the choosen registration form (field reg(String): "phone" or "mail").

      I need to seperate it somehow as the email-registrated-user needs to verify the email.


      AuthOptionActivity



      public class AuthOptionActivity extends AppCompatActivity 

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_authoption);
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
      getWindow().setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.move));

      this.checkAuthStatus();


      @Override
      public void onBackPressed()
      findViewById(R.id.activity_authoption_logo).setTransitionName(null);
      super.onBackPressed();
      /** Problem occured: SharedViewElement will be visible after App was closed.
      * Reason: The View will try to perform the ExitTransition
      * Solution 1: Delete super.onBackPressed(); and override with finish();
      * Solution 2: Set Transitionname to Null**/


      /**The SlideEnter Transition is variable, on First Startup we want a smooth slide in,
      * for phoneauth we want a Left-Side Slide and for Email a Right-Side Slide.
      * The Exit Animation is always slide-out-bottom-smooth.
      * The Reenter Animation is always slide-in-bottom-smooth and due to overlapping
      * the ExitTransition of the View before BackPress will be hidden and is always 0**/

      private void performFragmentTransaction(Fragment mFragment, String mTag, Boolean mAddToBackStack, int mEnterTransition)
      FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();
      mFragmentTransaction.setCustomAnimations(mEnterTransition, 0, R.anim.slide_in_bottom_smooth, 0);
      if(mAddToBackStack)
      mFragmentTransaction.addToBackStack(mTag);

      mFragmentTransaction.replace(R.id.activity_authoption_container, mFragment, mTag);
      mFragmentTransaction.commit();



      /**Check Auth Status: if CurrentUser != null but not Email verified -> Show MailAuth**/
      private void checkAuthStatus()
      if(FirebaseAuth.getInstance().getCurrentUser()!=null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
      //very bad way to force a backstack, still looking for a solution
      this.showAuthOptionFragment();
      this.showMailAuth();
      else
      this.showAuthOptionFragment();



      /**Handle Fragment Transaction including Listener**/
      private void showAuthOptionFragment()
      this.performFragmentTransaction(AuthOptionFragment.newInstance(new AuthOptionFragment.ClickListener()
      @Override
      public void onMail()
      showMailAuth();


      @Override
      public void onPhone()
      showPhoneAuth();

      ), "AuthOption", false, R.anim.slide_in_bottom);


      private void showPhoneAuth()
      this.performFragmentTransaction(_PhoneAuthFragment.newInstance(new _PhoneAuthFragment.AuthStatusListener()
      @Override
      public void onCancel()
      //PhoneAuthFragment contains a "back" Button it will fire "onCancel()"
      onBackPressed();


      @Override
      public void onSuccess()
      //show LoadingScreen

      ), "PhoneAuth", true, R.anim.slide_in_left_smooth);


      private void showMailAuth()
      this.performFragmentTransaction(_MailAuthFragment.newInstance(new _MailAuthFragment.AuthStatusListener()
      @Override
      public void onCancel()
      //MailAuthFragment contains a "back" Button it will fire "onCancel()"
      onBackPressed();


      @Override
      public void onSuccess()
      //show LoadingScreen

      ), "MailAuth", true, R.anim.slide_in_right_smooth);






      For this activity I have some questions:

      1. I am checking the Auth Status & email again to decide which fragment to show. It's easy and simple, but repetitive (it will occur again in MailAuthFragment). Is it a common way to repetitive use FirebaseAuth instances?


      2. I have seen a couple of fragment -> activity communication solutions using onAttach etc. Is my solution to pass a CustomListener(interface) in the newInstance method okay? Is there any bug that could occur using it that way?

      I pretty much like it as it makes the handling easier.



      MailAuthOptionFragment



      public class _MailAuthFragment extends Fragment 

      public interface AuthStatusListener
      void onCancel();
      void onSuccess();


      private AuthStatusListener mCallback;
      private String mActiveWindow;
      private CheckCancelButton mCheckCancelButton;

      private String mEmail;
      private String mPassword;

      @Override
      public void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);


      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
      View mView = inflater.inflate(R.layout.fragment_mailauth, container, false);
      this.checkAuthStatus();
      this.initButton(mView);
      return mView;


      /**PUBLIC METHODS**/

      /**Set the Fragment Listener for AuthOptionActivity**/
      public void setListener(AuthStatusListener mCallback)
      this.mCallback = mCallback;


      /**Replaces hard coded Instances as Listener will be passed directly**/
      public static _MailAuthFragment newInstance(AuthStatusListener mCallback)
      _MailAuthFragment mFragment = new _MailAuthFragment();
      mFragment.setListener(mCallback);
      return mFragment;


      /**PRIVATE METHODS**/

      /**Check AuthStatus, if CurrentUser!=null but not verified -> Show VerificationScreen**/
      private void checkAuthStatus()
      if(FirebaseAuth.getInstance().getCurrentUser() != null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
      this.showConfirmEmailSubFragment(R.anim.slide_in_right_smooth);
      else
      this.showEnterEmailSubFragment(R.anim.slide_in_right_smooth);



      /**Handle Registration Process Fragments**/
      private void performFragmentTransaction(Fragment mFragment, String mTag, int mEnterAnim)
      mActiveWindow = mTag;
      FragmentTransaction mFragmentTransaction = getChildFragmentManager().beginTransaction();
      mFragmentTransaction.setCustomAnimations(mEnterAnim, 0);
      mFragmentTransaction.replace(R.id.fragment_mailauth_container, mFragment, mTag);
      mFragmentTransaction.commit();


      /**MailAuth receives any valid TextChange from SubFragment**/
      private void showEnterEmailSubFragment(int mEnterAnim)

      this.performFragmentTransaction(EnterMailSubFragment.newInstance(new EnterMailSubFragment.EnterMailListener()
      @Override
      public void onEmailChanged(String mEmail)
      _MailAuthFragment.this.mEmail = mEmail;


      @Override
      public void onPasswordChanged(String mPassword)
      _MailAuthFragment.this.mPassword = mPassword;

      ), "EnterMail", mEnterAnim);



      /**MailAuth receives resend VerificationEmailRequest from SubFragment**/
      private void showConfirmEmailSubFragment(int mEnterAnim)
      this.performFragmentTransaction(new ConfirmMailSubFragment(), "ConfirmMail", R.anim.slide_in_right_smooth);


      private void initButton(final View mView)
      /**Custom Button using AfterEffects, Bodymovin and LottieView, contains some commands like "transform to tick"**/
      mCheckCancelButton = new CheckCancelButton((LottieAnimationView)mView.findViewById(R.id.fragment_mailauth_nextBtn));
      mCheckCancelButton.setCustomClickListener(new CheckCancelButton.CheckCancelButtonClickListener()
      @Override
      public void onClick()
      switch(mActiveWindow)
      case "EnterMail":
      // the received Email and Password will be passed to AuthHandlerClass - not implemented yet
      break;
      case "ConfirmMail":
      // the AuthHandler will reloard the currentUser and check for email verification Status - not implemented yet
      break;


      );





      Checking AuthStatus again and choosing wether to show the EnterEmailSubFragment or the ConfirmEmailSubFragment. This class contains a button handling both SubFragment pages. This leads to that switch-case method. Not sure if that is a proper way.



      EnterMailSubFragment



      public class EnterMailSubFragment extends Fragment 

      public interface EnterMailListener
      void onEmailChanged(String mEmail);
      void onPasswordChanged(String mPassword);


      private EnterMailListener mCallback;
      private EditText mEmail, mPassword;
      private ImageView mEmailWarning, mPasswordWarning;

      @Override
      public void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);

      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
      View mView = inflater.inflate(R.layout.subfragment_mailauth, container, false);
      this.initUiWidgets(mView);
      this.initEditText(mView);
      return mView;


      public void setEnterMailListener(EnterMailListener mMailListener)
      this.mCallback = mMailListener;


      public static EnterMailSubFragment newInstance(EnterMailListener mMailListener)
      EnterMailSubFragment mFragment = new EnterMailSubFragment();
      mFragment.setEnterMailListener(mMailListener);
      return mFragment;


      private void initUiWidgets(View mView)
      mEmail = mView.findViewById(R.id.subfragment_mailauth_email_ET);
      mPassword = mView.findViewById(R.id.subfragment_mailauth_password_et);
      mEmailWarning = mView.findViewById(R.id.subfragment_mailauth_email_warning);
      mPasswordWarning = mView.findViewById(R.id.subfragment_mailauth_password_warning);


      /**Any Valid Entry will be passed to MailFragment**/

      private void initEditText(final View mView)
      mEmail.addTextChangedListener(new TextWatcher()
      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after)



      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count)



      @Override
      public void afterTextChanged(Editable s)
      if(mEmail.getText() != null && Patterns.EMAIL_ADDRESS.matcher(mEmail.getText().toString()).matches())
      mEmailWarning.setVisibility(View.GONE);
      mCallback.onEmailChanged(mEmail.getText().toString());
      else
      mEmailWarning.setVisibility(View.VISIBLE);


      );

      mPassword.addTextChangedListener(new TextWatcher()
      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after)



      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count)


      @Override
      public void afterTextChanged(Editable s)
      if(mPassword.getText() != null && mPassword.getText().length() >= 6)
      mPasswordWarning.setVisibility(View.GONE);
      mCallback.onPasswordChanged(mPassword.getText().toString());
      else
      mPasswordWarning.setVisibility(View.VISIBLE);


      );






      The Textwatcher checks every entry and transfers it to the MailAuthFragment as MailAuthFragment handels the button event (this is for design puposes, I want the content to move and the button is meant to stay in its position).



      ConfirmMailAuthSubFragment



      public class ConfirmMailSubFragment extends Fragment 

      public interface ConfirmMailListener
      void onResendEmail();


      private ConfirmMailListener mCallback;

      @Override
      public void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);


      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
      View mView = inflater.inflate(R.layout.subfragment_confirmmail, container, false);

      return mView;


      public void setConfirmMailListener(ConfirmMailListener mCallback)
      this.mCallback = mCallback;


      public static ConfirmMailSubFragment newInstance(ConfirmMailListener mCallback)
      ConfirmMailSubFragment mFragment = new ConfirmMailSubFragment();
      mFragment.setConfirmMailListener(mCallback);
      return mFragment;





      Nothing special here yet. It will handle the Button Event "Resend Verification Mail" and transfer it to MailAuthFragment.



      I know it's a very early stage of my code but as beautiful as it looks with that slide in animations I am not sure if I am running in the wrong direction or making stuff unnecessary complex.









      share









      $endgroup$




      I am developing another bigger project, I want to try a simple DatingApp and currently I try to develope a Login and Registration Form. There is no special register / login button, the code will later decide wether email is registered (-> login) or not (-> register). But even though it's working I am not sure if I make things to complex:


      First I want so show a very simple overview of the logic I try to develope:



      enter image description here





      The App launches with the LogoActivity as a simple SplashScreen. In here the Activity decides which Activity and Fragment is about to be displayed next. It has a sharedElementTransition connected to the AuthOptionActivity.


      The AuthOptionActivity only contains the Logo and a fragment Container.

      Depending on the AuthStatus it will show the AuthOptionFragment, containing a Layout with two Buttons. Here you can decide which way you want to use for your registration.


      In case there is for example an email-registered user but he is not verified yet the AuthOptionActivity will show the MailAuthFragment instead of the AuthOptionFragment.


      The MailAuthOptionFragment itselfs contains another two ChildFragments.

      The EnterMailSubFragment contains two EditText-Views and the ConfirmMailSubFragment is just a Text containing the Email Adress and a clickable resend textview (not implemented yet).


      The code so far implemented is working but it is not that clear as I want it to be.

      Logo Activity



      public class LogoActivity extends AppCompatActivity {

      private ImageView mLogo;
      private Handler mHandler;

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_logo);
      this.init();


      private void init()
      mLogo = findViewById(R.id.activity_logo_logo);
      AuthHandler.performStartUpCheck(new AuthHandler.StartupAuthStatus()
      @Override
      public void noUser()
      Toast.makeText(LogoActivity.this, "No User", Toast.LENGTH_SHORT).show();
      performSharedElementTransactionToAuthOption();


      @Override
      public void onError(String e)
      Toast.makeText(LogoActivity.this, e, Toast.LENGTH_SHORT).show();
      performSharedElementTransactionToAuthOption();


      @Override
      public void onPhone()
      Toast.makeText(LogoActivity.this, "Phone", Toast.LENGTH_SHORT).show();
      //direct to loadingActivity


      @Override
      public void onEmail(boolean isVerified)
      Toast.makeText(LogoActivity.this, "Email" + String.valueOf(isVerified), Toast.LENGTH_SHORT).show();
      if(isVerified)
      //direct to LoadingActivity
      else
      performSharedElementTransactionToAuthOption();


      );
      //this.performSharedElementTransaction();


      private void performSharedElementTransactionToAuthOption()
      //check for auth and proceed to Loading
      Intent pIntent = new Intent(LogoActivity.this, AuthOptionActivity.class);
      ActivityOptions mOptions = ActivityOptions.makeSceneTransitionAnimation(LogoActivity.this, mLogo, mLogo.getTransitionName());
      startActivity(pIntent, mOptions.toBundle());



      private void performTransactionToLoadingScreen()
      /**dummy**/


      @Override
      protected void onStop()
      //Call finish here to avoid flickering
      this.finish();
      super.onStop();





      Nothing so special here, I am quite happy with that class. Disregard some comments, they are just for me as a reminder.


      AuthHandler



      public class AuthHandler 

      public interface StartupAuthStatus
      void noUser();
      void onError(String e);
      void onPhone();
      void onEmail(boolean isVerified);


      public interface SignInStatus
      void onEmail(boolean isVerified);


      private FirebaseAuth mAuth;
      private FirebaseFirestore mFirestore;

      /**STARTUP PROCEDURE**/

      public static void performStartUpCheck(final StartupAuthStatus mCallback)
      final FirebaseAuth mAuth = FirebaseAuth.getInstance();
      checkStartupAuthStatus(mAuth, mCallback);



      private static void checkStartupAuthStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
      mAuth = FirebaseAuth.getInstance();
      checkForCurrentUser(mAuth,mCallback);


      private static void checkForCurrentUser(FirebaseAuth mAuth, StartupAuthStatus mCallback)
      if(mAuth.getCurrentUser()!=null)
      checkRegistrationMethod(mAuth, mCallback);
      else
      mCallback.noUser();



      private static void checkRegistrationMethod(final FirebaseAuth mAuth, final StartupAuthStatus mCallback)
      if(mAuth.getUid() == null)
      mCallback.onError("NullPointerInUID");
      return;

      FirebaseFirestore.getInstance().collection("Registration").document(mAuth.getUid()).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
      @Override
      public void onComplete(@NonNull Task<DocumentSnapshot> task)
      if(task.getResult() != null && task.getResult().exists())
      Map<String, Object> mData = task.getResult().getData();
      String mRegistrationForm = (String) mData.get("reg");
      if(mRegistrationForm.equals("mail"))
      checkMailVerificationStatus(mAuth, mCallback);
      else if(mRegistrationForm.equals("phone"))
      mCallback.onPhone();



      ).addOnFailureListener(new OnFailureListener()
      @Override
      public void onFailure(@NonNull Exception e)
      mCallback.onError(e.getMessage());
      mAuth.signOut();

      );


      private static void checkMailVerificationStatus(FirebaseAuth mAuth, StartupAuthStatus mCallback)
      if(mAuth.getCurrentUser().isEmailVerified())
      mCallback.onEmail(true);
      else
      mCallback.onEmail(false);



      /**LOGIN PROCEDURE**/

      public static void enterUserWithEmailAndPassword(String mEmail, String mPassword)
      FirebaseAuth mAuth = FirebaseAuth.getInstance();
      createUserWithEmailAndPassword(mAuth, mEmail, mPassword);


      private static void createUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



      private static void signUserWithEmailAndPassword(FirebaseAuth mAuth, String mEmail, String mPassword)



      private static void sendVerificationEmail(FirebaseAuth mAuth)



      private static void setupRegistrationModel(String mModelType)



      /**DELETE PROCEDURE**/





      This class is made to "outsource" the code mess. Here I am not sure if it's a common or even usefull way to handle this. The Database contains Users (with a lot of Data later) and a Pool of Registrations, here I only store the choosen registration form (field reg(String): "phone" or "mail").

      I need to seperate it somehow as the email-registrated-user needs to verify the email.


      AuthOptionActivity



      public class AuthOptionActivity extends AppCompatActivity 

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_authoption);
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
      getWindow().setSharedElementEnterTransition(TransitionInflater.from(this).inflateTransition(android.R.transition.move));

      this.checkAuthStatus();


      @Override
      public void onBackPressed()
      findViewById(R.id.activity_authoption_logo).setTransitionName(null);
      super.onBackPressed();
      /** Problem occured: SharedViewElement will be visible after App was closed.
      * Reason: The View will try to perform the ExitTransition
      * Solution 1: Delete super.onBackPressed(); and override with finish();
      * Solution 2: Set Transitionname to Null**/


      /**The SlideEnter Transition is variable, on First Startup we want a smooth slide in,
      * for phoneauth we want a Left-Side Slide and for Email a Right-Side Slide.
      * The Exit Animation is always slide-out-bottom-smooth.
      * The Reenter Animation is always slide-in-bottom-smooth and due to overlapping
      * the ExitTransition of the View before BackPress will be hidden and is always 0**/

      private void performFragmentTransaction(Fragment mFragment, String mTag, Boolean mAddToBackStack, int mEnterTransition)
      FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();
      mFragmentTransaction.setCustomAnimations(mEnterTransition, 0, R.anim.slide_in_bottom_smooth, 0);
      if(mAddToBackStack)
      mFragmentTransaction.addToBackStack(mTag);

      mFragmentTransaction.replace(R.id.activity_authoption_container, mFragment, mTag);
      mFragmentTransaction.commit();



      /**Check Auth Status: if CurrentUser != null but not Email verified -> Show MailAuth**/
      private void checkAuthStatus()
      if(FirebaseAuth.getInstance().getCurrentUser()!=null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
      //very bad way to force a backstack, still looking for a solution
      this.showAuthOptionFragment();
      this.showMailAuth();
      else
      this.showAuthOptionFragment();



      /**Handle Fragment Transaction including Listener**/
      private void showAuthOptionFragment()
      this.performFragmentTransaction(AuthOptionFragment.newInstance(new AuthOptionFragment.ClickListener()
      @Override
      public void onMail()
      showMailAuth();


      @Override
      public void onPhone()
      showPhoneAuth();

      ), "AuthOption", false, R.anim.slide_in_bottom);


      private void showPhoneAuth()
      this.performFragmentTransaction(_PhoneAuthFragment.newInstance(new _PhoneAuthFragment.AuthStatusListener()
      @Override
      public void onCancel()
      //PhoneAuthFragment contains a "back" Button it will fire "onCancel()"
      onBackPressed();


      @Override
      public void onSuccess()
      //show LoadingScreen

      ), "PhoneAuth", true, R.anim.slide_in_left_smooth);


      private void showMailAuth()
      this.performFragmentTransaction(_MailAuthFragment.newInstance(new _MailAuthFragment.AuthStatusListener()
      @Override
      public void onCancel()
      //MailAuthFragment contains a "back" Button it will fire "onCancel()"
      onBackPressed();


      @Override
      public void onSuccess()
      //show LoadingScreen

      ), "MailAuth", true, R.anim.slide_in_right_smooth);






      For this activity I have some questions:

      1. I am checking the Auth Status & email again to decide which fragment to show. It's easy and simple, but repetitive (it will occur again in MailAuthFragment). Is it a common way to repetitive use FirebaseAuth instances?


      2. I have seen a couple of fragment -> activity communication solutions using onAttach etc. Is my solution to pass a CustomListener(interface) in the newInstance method okay? Is there any bug that could occur using it that way?

      I pretty much like it as it makes the handling easier.



      MailAuthOptionFragment



      public class _MailAuthFragment extends Fragment 

      public interface AuthStatusListener
      void onCancel();
      void onSuccess();


      private AuthStatusListener mCallback;
      private String mActiveWindow;
      private CheckCancelButton mCheckCancelButton;

      private String mEmail;
      private String mPassword;

      @Override
      public void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);


      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
      View mView = inflater.inflate(R.layout.fragment_mailauth, container, false);
      this.checkAuthStatus();
      this.initButton(mView);
      return mView;


      /**PUBLIC METHODS**/

      /**Set the Fragment Listener for AuthOptionActivity**/
      public void setListener(AuthStatusListener mCallback)
      this.mCallback = mCallback;


      /**Replaces hard coded Instances as Listener will be passed directly**/
      public static _MailAuthFragment newInstance(AuthStatusListener mCallback)
      _MailAuthFragment mFragment = new _MailAuthFragment();
      mFragment.setListener(mCallback);
      return mFragment;


      /**PRIVATE METHODS**/

      /**Check AuthStatus, if CurrentUser!=null but not verified -> Show VerificationScreen**/
      private void checkAuthStatus()
      if(FirebaseAuth.getInstance().getCurrentUser() != null && !FirebaseAuth.getInstance().getCurrentUser().isEmailVerified())
      this.showConfirmEmailSubFragment(R.anim.slide_in_right_smooth);
      else
      this.showEnterEmailSubFragment(R.anim.slide_in_right_smooth);



      /**Handle Registration Process Fragments**/
      private void performFragmentTransaction(Fragment mFragment, String mTag, int mEnterAnim)
      mActiveWindow = mTag;
      FragmentTransaction mFragmentTransaction = getChildFragmentManager().beginTransaction();
      mFragmentTransaction.setCustomAnimations(mEnterAnim, 0);
      mFragmentTransaction.replace(R.id.fragment_mailauth_container, mFragment, mTag);
      mFragmentTransaction.commit();


      /**MailAuth receives any valid TextChange from SubFragment**/
      private void showEnterEmailSubFragment(int mEnterAnim)

      this.performFragmentTransaction(EnterMailSubFragment.newInstance(new EnterMailSubFragment.EnterMailListener()
      @Override
      public void onEmailChanged(String mEmail)
      _MailAuthFragment.this.mEmail = mEmail;


      @Override
      public void onPasswordChanged(String mPassword)
      _MailAuthFragment.this.mPassword = mPassword;

      ), "EnterMail", mEnterAnim);



      /**MailAuth receives resend VerificationEmailRequest from SubFragment**/
      private void showConfirmEmailSubFragment(int mEnterAnim)
      this.performFragmentTransaction(new ConfirmMailSubFragment(), "ConfirmMail", R.anim.slide_in_right_smooth);


      private void initButton(final View mView)
      /**Custom Button using AfterEffects, Bodymovin and LottieView, contains some commands like "transform to tick"**/
      mCheckCancelButton = new CheckCancelButton((LottieAnimationView)mView.findViewById(R.id.fragment_mailauth_nextBtn));
      mCheckCancelButton.setCustomClickListener(new CheckCancelButton.CheckCancelButtonClickListener()
      @Override
      public void onClick()
      switch(mActiveWindow)
      case "EnterMail":
      // the received Email and Password will be passed to AuthHandlerClass - not implemented yet
      break;
      case "ConfirmMail":
      // the AuthHandler will reloard the currentUser and check for email verification Status - not implemented yet
      break;


      );





      Checking AuthStatus again and choosing wether to show the EnterEmailSubFragment or the ConfirmEmailSubFragment. This class contains a button handling both SubFragment pages. This leads to that switch-case method. Not sure if that is a proper way.



      EnterMailSubFragment



      public class EnterMailSubFragment extends Fragment 

      public interface EnterMailListener
      void onEmailChanged(String mEmail);
      void onPasswordChanged(String mPassword);


      private EnterMailListener mCallback;
      private EditText mEmail, mPassword;
      private ImageView mEmailWarning, mPasswordWarning;

      @Override
      public void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);

      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
      View mView = inflater.inflate(R.layout.subfragment_mailauth, container, false);
      this.initUiWidgets(mView);
      this.initEditText(mView);
      return mView;


      public void setEnterMailListener(EnterMailListener mMailListener)
      this.mCallback = mMailListener;


      public static EnterMailSubFragment newInstance(EnterMailListener mMailListener)
      EnterMailSubFragment mFragment = new EnterMailSubFragment();
      mFragment.setEnterMailListener(mMailListener);
      return mFragment;


      private void initUiWidgets(View mView)
      mEmail = mView.findViewById(R.id.subfragment_mailauth_email_ET);
      mPassword = mView.findViewById(R.id.subfragment_mailauth_password_et);
      mEmailWarning = mView.findViewById(R.id.subfragment_mailauth_email_warning);
      mPasswordWarning = mView.findViewById(R.id.subfragment_mailauth_password_warning);


      /**Any Valid Entry will be passed to MailFragment**/

      private void initEditText(final View mView)
      mEmail.addTextChangedListener(new TextWatcher()
      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after)



      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count)



      @Override
      public void afterTextChanged(Editable s)
      if(mEmail.getText() != null && Patterns.EMAIL_ADDRESS.matcher(mEmail.getText().toString()).matches())
      mEmailWarning.setVisibility(View.GONE);
      mCallback.onEmailChanged(mEmail.getText().toString());
      else
      mEmailWarning.setVisibility(View.VISIBLE);


      );

      mPassword.addTextChangedListener(new TextWatcher()
      @Override
      public void beforeTextChanged(CharSequence s, int start, int count, int after)



      @Override
      public void onTextChanged(CharSequence s, int start, int before, int count)


      @Override
      public void afterTextChanged(Editable s)
      if(mPassword.getText() != null && mPassword.getText().length() >= 6)
      mPasswordWarning.setVisibility(View.GONE);
      mCallback.onPasswordChanged(mPassword.getText().toString());
      else
      mPasswordWarning.setVisibility(View.VISIBLE);


      );






      The Textwatcher checks every entry and transfers it to the MailAuthFragment as MailAuthFragment handels the button event (this is for design puposes, I want the content to move and the button is meant to stay in its position).



      ConfirmMailAuthSubFragment



      public class ConfirmMailSubFragment extends Fragment 

      public interface ConfirmMailListener
      void onResendEmail();


      private ConfirmMailListener mCallback;

      @Override
      public void onCreate(@Nullable Bundle savedInstanceState)
      super.onCreate(savedInstanceState);


      @Nullable
      @Override
      public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
      View mView = inflater.inflate(R.layout.subfragment_confirmmail, container, false);

      return mView;


      public void setConfirmMailListener(ConfirmMailListener mCallback)
      this.mCallback = mCallback;


      public static ConfirmMailSubFragment newInstance(ConfirmMailListener mCallback)
      ConfirmMailSubFragment mFragment = new ConfirmMailSubFragment();
      mFragment.setConfirmMailListener(mCallback);
      return mFragment;





      Nothing special here yet. It will handle the Button Event "Resend Verification Mail" and transfer it to MailAuthFragment.



      I know it's a very early stage of my code but as beautiful as it looks with that slide in animations I am not sure if I am running in the wrong direction or making stuff unnecessary complex.







      java android user-interface firebase





      share












      share










      share



      share










      asked 2 mins ago









      J. LoJ. Lo

      62




      62




















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215717%2fcodereview-of-a-firebase-login-registration-process%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215717%2fcodereview-of-a-firebase-login-registration-process%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          कुँवर स्रोत दिक्चालन सूची"कुँवर""राणा कुँवरके वंशावली"

          Why is a white electrical wire connected to 2 black wires?How to wire a light fixture with 3 white wires in box?How should I wire a ceiling fan when there's only three wires in the box?Two white, two black, two ground, and red wire in ceiling box connected to switchWhy is there a white wire connected to multiple black wires in my light box?How to wire a light with two white wires and one black wireReplace light switch connected to a power outlet with dimmer - two black wires to one black and redHow to wire a light with multiple black/white/green wires from the ceiling?Ceiling box has 2 black and white wires but fan/ light only has 1 of eachWhy neutral wire connected to load wire?Switch with 2 black, 2 white, 2 ground and 1 red wire connected to ceiling light and a receptacle?

          चैत्य भूमि चित्र दीर्घा सन्दर्भ बाहरी कडियाँ दिक्चालन सूची"Chaitya Bhoomi""Chaitya Bhoomi: Statue of Equality in India""Dadar Chaitya Bhoomi: Statue of Equality in India""Ambedkar memorial: Centre okays transfer of Indu Mill land"चैत्यभमि