0

I know there's a few question like this but they either are not what I wanted or I'm just somehow not able do it. What I want is the user, during registration, are required to write username, email and password. Then when user sign in, user can use username/email to login. I found this post:

Firebase login and signup with username

But just like this guy, I don't know how others link to my code. I did try the method in the answer but failed. Do I need to store the username in the database? If yes, how? Really hoping you guys can help me, still a rookie here.

SignUpActivity:

public class SignUpActivity extends AppCompatActivity implements View.OnClickListener {

@InjectView(R.id.fab)
FloatingActionButton fab;
@InjectView(R.id.cv_add)
CardView cvAdd;
private EditText editTextEmail;
private EditText editTextPassword;
private EditText editTextUsername;
private ProgressDialog progressDialog;
private Button bt_signup;

private FirebaseAuth firebaseAuth;
private DatabaseReference mDatabase;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_up);
    ButterKnife.inject(this);

    firebaseAuth = FirebaseAuth.getInstance();

    if(firebaseAuth.getCurrentUser() != null){

        finish();

        startActivity(new Intent(getApplicationContext(), MainActivity.class));
    }


    editTextEmail = (EditText) findViewById(R.id.editTextEmail);
    editTextPassword = (EditText) findViewById(R.id.editTextPassword);
    editTextUsername = (EditText) findViewById(R.id.editTextUsername);
    bt_signup = (Button) findViewById(R.id.bt_signup);
    progressDialog = new ProgressDialog(this);
    bt_signup.setOnClickListener(this);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ShowEnterAnimation();
    }
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            animateRevealClose();

        }

    });

}

private void registerUser(){

    String email = editTextEmail.getText().toString().trim();
    String password  = editTextPassword.getText().toString().trim();
    final String username = editTextUsername.getText().toString().trim();

    if(TextUtils.isEmpty(email)){
        Toast.makeText(this,"Please enter email",Toast.LENGTH_LONG).show();
        return;
    }

    if(TextUtils.isEmpty(password)){
        Toast.makeText(this,"Please enter password",Toast.LENGTH_LONG).show();
        return;
    }

    if(TextUtils.isEmpty(username)){
        Toast.makeText(this,"Please enter username",Toast.LENGTH_LONG).show();
        return;
    }

    progressDialog.setMessage("Registering Please Wait...");
    progressDialog.show();
    mDatabase = FirebaseDatabase.getInstance().getReference().child("Users");

    firebaseAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {

                    if(task.isSuccessful()){
                        User newUser = new User(firebaseAuth.getCurrentUser().getEmail(),username);

                        mDatabase.child(firebaseAuth.getCurrentUser().getUid()).setValue(newUser);
                        finish();
                        startActivity(new Intent(getApplicationContext(), SignInActivity.class));
                    }else{

                        Toast.makeText(SignUpActivity.this,"Registration Error",Toast.LENGTH_LONG).show();
                    }
                    progressDialog.dismiss();
                }
            });

}


private void ShowEnterAnimation() {
    Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.fabtransition);
    getWindow().setSharedElementEnterTransition(transition);

    transition.addListener(new Transition.TransitionListener() {
        @Override
        public void onTransitionStart(Transition transition) {
            cvAdd.setVisibility(View.GONE);
        }

        @Override
        public void onTransitionEnd(Transition transition) {
            transition.removeListener(this);
            animateRevealShow();
        }

        @Override
        public void onTransitionCancel(Transition transition) {

        }

        @Override
        public void onTransitionPause(Transition transition) {

        }

        @Override
        public void onTransitionResume(Transition transition) {

        }


    });
}

public void animateRevealShow() {
    Animator mAnimator = ViewAnimationUtils.createCircularReveal(cvAdd, cvAdd.getWidth()/2,0, fab.getWidth() / 2, cvAdd.getHeight());
    mAnimator.setDuration(500);
    mAnimator.setInterpolator(new AccelerateInterpolator());
    mAnimator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
        }

        @Override
        public void onAnimationStart(Animator animation) {
            cvAdd.setVisibility(View.VISIBLE);
            super.onAnimationStart(animation);
        }
    });
    mAnimator.start();
}

public void animateRevealClose() {
    Animator mAnimator = ViewAnimationUtils.createCircularReveal(cvAdd,cvAdd.getWidth()/2,0, cvAdd.getHeight(), fab.getWidth() / 2);
    mAnimator.setDuration(500);
    mAnimator.setInterpolator(new AccelerateInterpolator());
    mAnimator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            cvAdd.setVisibility(View.INVISIBLE);
            super.onAnimationEnd(animation);
            fab.setImageResource(R.drawable.plus);
            SignUpActivity.super.onBackPressed();
        }

        @Override
        public void onAnimationStart(Animator animation) {
            super.onAnimationStart(animation);
        }
    });
    mAnimator.start();
}
@Override
public void onBackPressed() {
    animateRevealClose();
}


@Override
public void onClick(View view) {
    if(view == bt_signup){
        registerUser();
    }
}
}

User.Java

import com.google.firebase.database.IgnoreExtraProperties;

@IgnoreExtraProperties
public class User {

private String username;
private String password;

public User() {

}


public User(String username, String password)
{
    this.username = username;  
    this.password = password;
}


public String getUsername()
{
    return username;
}
public void setUsername(String username)
{
    this.username = username;
}
public String getPassword()
{
    return password;
}
public void setPassword(String password)
{
    this.password = password;
}

}

My database Data stored from my other activity.

Security rules

I turned some of the code into comments, those are the code when I attempt to store the username in the database, but failed even though my other activity use the same method. I've spent the whole morning just trying to allow users to login with username, please help.

Edited: Added mDatabase.

Edited(2): Update SignUpActivity, added database and rules.

Community
  • 1
  • 1
Zephyros
  • 77
  • 7
  • 1
    According to what I understood from your question, you want users to login with an username/email and password, which wouldn't work if you're using Firebase email/password authentication because the `signInWithEmailAndPassword` method specifically asks for an email and a password to sign in the user, but it's possible to store additional data of a user in database at the sign up process. Also the selected answer in the question you've linked doesn't provide a way to sign in a user using username and password. I could post a code snippet on how to store additional user info at user registration – RamithDR Mar 18 '17 at 10:01
  • Thanks for the reply, I thought it was possible, guess that's what the firebase lack. Yes, do post the code, really need any help I can get. Thanks in advance. – Zephyros Mar 18 '17 at 12:18
  • Please check the code snippet below, I'd be happy to help if you need further clarifications. @Zephyros – RamithDR Mar 18 '17 at 14:07

1 Answers1

0

This code snippet stores a user in the database after successful registration under "Users" -> "User ID" node of Firebase database, this is how it would look in the database:

  "Users" : {
    "7Ak7qkAi6cTtDuIpEGsBUXdgNZT2" : {
      "user_email" : "zephyros@gmail.com",
      "user_name" : "Zephyros"
    }
  }

Here's the Java code:

 mDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
 mAuth.createUserWithEmailAndPassword(email, pass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {

            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {

            //after successfully registering user with email and pass,
            //user details are stored in database under the unique user ID
            if(task.isSuccessful()){

                User newUser = new User(mAuth.getCurrentUser().getEmail(),username);

                mDatabase.child(mAuth.getCurrentUser().getUid()).setValue(newUser);



        }
    ...

As you can see my User class only contains user name and user email attributes, you can expand the class with more attributes according to your requirement.

HTH, comment below if you need any further clarifications.

EDIT 1

Database rules do affect your read and write operations and according to your ruleset, you've added a rule for write operations. I advised you to remove it temporarily to pin point the exact problem. Use this ruleset instead:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

EDIT 2

The reason for username stored as password and email is stored as username is because of your User class constructor take username and password. Your User class should be something like this:

public class User {

private String email;
private String username;

public User() {

}


public User(String email, String username)
{
    this.email = email;  
    this.username = username;
}


public String getUsername()
{
    return username;
}
public void setUsername(String username)
{
    this.username = username;
}
public String getEmail()
{
    return email;
}
public void setEmail(String email)
{
    this.email = email;
}

}
RamithDR
  • 2,103
  • 2
  • 25
  • 34
  • I tried your code, but nothing came out in my database. I did change the username into final string though. – Zephyros Mar 18 '17 at 14:50
  • Could update the question and post the code you tried? – RamithDR Mar 18 '17 at 14:57
  • 1
    Your Firebase code seems to be fine, the code I posted is from an ongoing project of mine which is working as intended. I feel something is off with the validation checks, what is `!validateForm()` ? Could you please try the code commenting out the valdiation checks inside the `registerUser()` method? – RamithDR Mar 18 '17 at 15:40
  • Still nothing after removed the validate, I'll update my activity again since I removed the animation code when posting here, will also add my layout and how my database currently looks like. Will the database rules affect it? – Zephyros Mar 19 '17 at 00:44
  • @Zephyros Take a look at my updated answer. The problem probably was that user registration goes successfully but the rule added for the write operation prevents writing the user info to the database. – RamithDR Mar 19 '17 at 03:37
  • Ok got it, the data finally appear in my database, but for some reason, my username is store as password and email is store as username. – Zephyros Mar 19 '17 at 04:58
  • All right, so now the email is store as username in my database, but not the username? Also, I would like to use back my rules which only allows the admin of the room to write his room, while allow anyone to write username/email into database. Sorry for all the trouble >. – Zephyros Mar 19 '17 at 05:28
  • @Zephyros When creating the User make sure you're creating the User object like `(email, username)` provided that you're using the class I posted. Please double check your class constructor as this is not an issue related to Firebase. As for the rules, it's better if you create another question with your project scenario. – RamithDR Mar 19 '17 at 05:34
  • Ok , finally it stores both of them, thank you very much for the advice and guidance. I will do so for the rules. ;D Again thank you and sorry if I caused any trouble. – Zephyros Mar 19 '17 at 05:55
  • @Zephyros No problem, I'm happy to help :) On a side note, checkout this Android Firebase course, it's free and built by Google. https://www.udacity.com/course/firebase-essentials-for-android--ud009 – RamithDR Mar 19 '17 at 06:00