简体   繁体   中英

App stops working when register button is clicked

i want to register then when clicked on register button a verification email is sent to the email address.on clicking the link in the email.the email is verified.and the user can now login from the login screen.

RegisterActivity.java

public class RegisterActivity extends AppCompatActivity {

private static final String TAG = "RegisterActivity";
private Context mContext;
private String email, username, password;
private EditText mEmail, mPassword, mUsername;
private TextView loadingPleaseWait;
private Button btnRegister;
private ProgressBar mProgressBar;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseMethods firebaseMethods;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
private String append = "";


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register);
    mContext = RegisterActivity.this;
    //mAuth = FirebaseAuth.getInstance();
    firebaseMethods = new FirebaseMethods(mContext);
    Log.d(TAG, "onCreate: started.");
    initWidgets();
    setupFirebaseAuth();
    init();
}

private void init(){
    btnRegister.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            email = mEmail.getText().toString();
            username = mUsername.getText().toString();
            password = mPassword.getText().toString();
            if(checkInputs(email, username, password)){
                mProgressBar.setVisibility(View.VISIBLE);
                loadingPleaseWait.setVisibility(View.VISIBLE);
                firebaseMethods.registerNewEmail(email, password, username);
            }
        }
    });
}

private boolean checkInputs(String email, String username, String password){
    Log.d(TAG, "checkInputs: checking inputs for null values.");
    if(email.equals("") || username.equals("") || password.equals("")){
        Toast.makeText(mContext, "All fields must be filled out.", Toast.LENGTH_SHORT).show();
        return false;
    }
    return true;
}

private void initWidgets(){
    Log.d(TAG, "initWidgets: Initializing Widgets.");
    mEmail = (EditText) findViewById(R.id.input_email);
    mUsername = (EditText) findViewById(R.id.input_username);
    btnRegister = (Button) findViewById(R.id.btn_register);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    loadingPleaseWait = (TextView) findViewById(R.id.loadingPleaseWait);
    mPassword = (EditText) findViewById(R.id.input_password);
    mContext = RegisterActivity.this;
    mProgressBar.setVisibility(View.GONE);
    loadingPleaseWait.setVisibility(View.GONE);

}

private boolean isStringNull(String string){
    Log.d(TAG, "isStringNull: checking string if null.");

    if(string.equals("")){
        return true;
    }
    else{
        return false;
    }
}


private void setupFirebaseAuth(){
    Log.d(TAG, "setupFirebaseAuth: setting up firebase auth.");

    mAuth = FirebaseAuth.getInstance();
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    myRef = mFirebaseDatabase.getReference();

    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();

            if (user != null) {
                // User is signed in
                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());

                myRef.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        //1st check: Make sure the username is not already in use
                        if(firebaseMethods.checkIfUsernameExists(username, dataSnapshot)){
                            append = myRef.push().getKey().substring(3,10);
                            Log.d(TAG, "onDataChange: username already exists. Appending random string to name: " + append);
                        }
                        username = username + append;

                        //add new user to the database
                        firebaseMethods.addNewUser(email, username, "", "", "");

                        Toast.makeText(mContext, "Signup successful. Sending verification email.", Toast.LENGTH_SHORT).show();

                        mAuth.signOut();
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });

                finish();

            } else {
                // User is signed out
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
            // ...
        }
    };
}

@Override
public void onStart() {
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}
}

Here are the firebase methods like to register new email,add new user, send verification email etc...

FirebaseMethods.java

public class FirebaseMethods {

private static final String TAG = "FirebaseMethods";

//firebase
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
private String userID;

private Context mContext;

public FirebaseMethods(Context context) {
    mAuth = FirebaseAuth.getInstance();
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    myRef = mFirebaseDatabase.getReference();
    mContext = context;

    if(mAuth.getCurrentUser() != null){
        userID = mAuth.getCurrentUser().getUid();
    }
}

public boolean checkIfUsernameExists(String username, DataSnapshot datasnapshot){
    Log.d(TAG, "checkIfUsernameExists: checking if " + username + " already exists.");

    User user = new User();

    for (DataSnapshot ds: datasnapshot.child(userID).getChildren()){
        Log.d(TAG, "checkIfUsernameExists: datasnapshot: " + ds);

        user.setUsername(ds.getValue(User.class).getUsername());
        Log.d(TAG, "checkIfUsernameExists: username: " + user.getUsername());

        if(StringManipulation.expandUsername(user.getUsername()).equals(username)){
            Log.d(TAG, "checkIfUsernameExists: FOUND A MATCH: " + user.getUsername());
            return true;
        }
    }
    return false;
}

/**
 * Register a new email and password to Firebase Authentication
 * @param email
 * @param password
 * @param username
 */
public void registerNewEmail(final String email, String password, final String username){
    mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());

                    // If sign in fails, display a message to the user. If sign in succeeds
                    // the auth state listener will be notified and logic to handle the
                    // signed in user can be handled in the listener.
                    if (!task.isSuccessful()) {
                        Toast.makeText(mContext, R.string.auth_failed,Toast.LENGTH_SHORT).show();

                    }
                    else if(task.isSuccessful()){
                        //send verification email
                        sendVerificationEmail();

                        userID = mAuth.getCurrentUser().getUid();
                        Log.d(TAG, "onComplete: Authstate changed: " + userID);
                    }

                }
            });
}

public void sendVerificationEmail(){
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    if (user != null){
        user.sendEmailVerification()
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()){

                        }else{
                            Toast.makeText(mContext,"Couldn't send verification email.",Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
}

public void addNewUser(String email, String username, String description, String website, String profile_photo){

    User user = new User( userID,  1,  email,  StringManipulation.condenseUsername(username) );

    myRef.child(mContext.getString(R.string.dbname_users))
            .child(userID)
            .setValue(user);


    UserAccountSettings settings = new UserAccountSettings(
            description,
            username,
            0,
            0,
            0,
            profile_photo,
            username,
            website
    );

    myRef.child(mContext.getString(R.string.dbname_user_account_settings))
            .child(userID)
            .setValue(settings);

}

}

This are the log lines....

01-09 13:16:06.014 21548-21548/com.example.vishal.myinstagram D/RegisterActivity: onAuthStateChanged:signed_out

01-09 13:16:06.015 21548-21588/com.example.vishal.myinstagram D/FA: Connected to remote service

01-09 13:16:06.015 21548-21588/com.example.vishal.myinstagram V/FA: Processing queued up service tasks: 4

01-09 13:16:06.017 21548-21994/com.example.vishal.myinstagram W/System: ClassLoader referenced unknown path: /data/data/com.google.android.gms/app_chimera/m/0000003a/n/arm64-v8a

01-09 13:16:11.043 21548-21588/com.example.vishal.myinstagram V/FA: Inactivity, disconnecting from the service

01-09 13:16:21.029 21548-21548/com.example.vishal.myinstagram W/Settings: Setting device_provisioned has moved from android.provider.Settings.Secure to android.provider.Settings.Global.

01-09 13:16:21.957 21548-21548/com.example.vishal.myinstagram W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.

01-09 13:16:32.737 21548-21548/com.example.vishal.myinstagram D/RegisterActivity: checkInputs: checking inputs for null values.

01-09 13:16:32.743 21548-21548/com.example.vishal.myinstagram W/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms

01-09 13:16:34.088 21548-21548/com.example.vishal.myinstagram D/FirebaseMethods: createUserWithEmail:onComplete:false

Thanks in advance...

So before you can set any OnClickListener on a view, you must first initialize a variable with findViewById(R.id.button_register) . For example,

private Button registerButton;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    registerButton = (Button) findViewById(R.id.button_register);
    registerButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //handle click event
        }
    });
    ...
}

It is worth a mention that if you are using the support library >26 you do not need to cast the view anymore and can omit the (Button) in the initialization of registerButton . Android Studio should even prompt you that casting is no longer necessary. https://stackoverflow.com/a/44903372/7900721

Now the R.id is something that is set upon the view in the layout XML file.

 <Button
 android:id="@+id/button_register"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/my_button_text"/>

Search for findViewById in the docs for more information https://developer.android.com/reference/android/view/View.html

Just a recommendation for some cleaner code that is more readable, I'd recommend creating a private variable of View.OnClickListener that you pass in as the listener as shown below.

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    fab.setOnClickListener(clickListener);
}

/**
 * Handle click listeners
 */
private View.OnClickListener clickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //handle click event here
    }
};

So if you begin to handle multiple click events, you could handle them in one section. As far as readability for others to maintain the code, it keeps methods such as onCreate() more concise with purpose of where each action is handled instead of scanning through multiple anonymous classes which would need to be instantiated for each setOnClickListener

我的问题解决了...他们在我的jason文件中有问题...无论如何感谢大家...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM