简体   繁体   English

单击注册按钮后,应用程序停止工作

[英]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 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... 这是Firebase的方法,例如注册新电子邮件,添加新用户,发送验证电子邮件等...

FirebaseMethods.java 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.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 D / FA:已连接到远程服务

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.015 21548-21588 / com.example.vishal.myinstagram V / FA:处理排队的服务任务: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:06.017 21548-21994 / com.example.vishal.myinstagram W / System:ClassLoader引用的未知路径:/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:11.043 21548-21588 / com.example.vishal.myinstagram V / FA:处于不活动状态,与服务断开连接

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.029 21548-21548 / com.example.vishal.myinstagram W / Settings:设置device_provisioned已从android.provider.Settings.Secure移至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:21.957 21548-21548 / com.example.vishal.myinstagram W / InputEventReceiver:尝试完成输入事件,但输入事件接收器已被处置。

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.737 21548-21548 / com.example.vishal.myinstagram D / RegisterActivity:checkInputs:检查输入是否为空值。

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

01-09 13:16:34.088 21548-21548/com.example.vishal.myinstagram D/FirebaseMethods: createUserWithEmail:onComplete:false 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) . 因此,在可以在视图上设置任何OnClickListener之前,必须首先使用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 . 值得一提的是,如果您使用支持库> 26,则不再需要强制转换视图,并且可以在registerButton的初始化中省略(Button) Android Studio should even prompt you that casting is no longer necessary. Android Studio甚至会提示您不再需要强制转换。 https://stackoverflow.com/a/44903372/7900721 https://stackoverflow.com/a/44903372/7900721

Now the R.id is something that is set upon the view in the layout XML file. 现在, R.id是在布局XML文件中的视图上设置的内容。

 <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 在文档中搜索findViewById以获取更多信息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. 只是对一些更易读的代码的建议,我建议创建一个View.OnClickListener私有变量,您将其作为侦听器传递,如下所示。

@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 就其他人维护代码的可读性而言,它使诸如onCreate()更简洁,以处理每个动作为目的,而不是扫描需要为每个setOnClickListener实例化的多个匿名类。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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