You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

进入注册Activity触发NullPointerException,需实现Firebase用户数据存储

注册页面打开即触发NullPointerException问题排查

问题概述

开发的Android应用进入Register Activity后立即崩溃,触发NullPointerException。该页面用于实现用户注册功能,计划将用户名、用户ID等信息存入Firebase实时数据库,但打开页面就崩溃。

错误日志

FATAL EXCEPTION: main
Process: com.example.movies4u, PID: 18933
java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.firebase.auth.FirebaseAuth$AuthStateListener.onAuthStateChanged(com.google.firebase.auth.FirebaseAuth)' on a null object reference
    at com.google.firebase.auth.zzl.run(com.google.firebase:firebase-auth@@21.0.3:1)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:224)
    at android.app.ActivityThread.main(ActivityThread.java:7081)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:928)

注册页面代码

package com.example.movies4u;

import static android.content.ContentValues.TAG;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.example.movies4u.Utils.FirebaseMethods;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthUserCollisionException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class activity_register extends AppCompatActivity {
    TextView HaveAccount;
    EditText inputUsername,inputEmail,inputPassword,inputConfirmPassword;
    String username,email,password;
    Button btnRegister;
    FirebaseAuth mAuth;
    ProgressBar pb;
    private String userID;
    private FirebaseAuth.AuthStateListener mAuthListener;
    private FirebaseMethods firebaseMethods;
    private FirebaseDatabase mFirebaseDatabase;
    private DatabaseReference myRef;

    private String append;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); //Hide status Bar
        setContentView(R.layout.activity_register);
        firebaseMethods =new FirebaseMethods(activity_register.this);

        HaveAccount= (TextView) findViewById(R.id.HaveAccount);
        pb = findViewById(R.id.progressBar3);
        inputUsername=findViewById(R.id.inputUsername);
        inputEmail=findViewById(R.id.inputEmail);
        inputPassword=findViewById(R.id.inputPassword);
        inputConfirmPassword=findViewById(R.id.inputConfirmPassword);
        btnRegister=findViewById(R.id.btnRegister);
        username=inputUsername.getText().toString();
        email=inputEmail.getText().toString();
        password=inputPassword.getText().toString();

        pb.setVisibility(View.GONE);
        HaveAccount.setOnClickListener(view -> {
            Intent loginintent=new Intent(activity_register.this,login_activity.class);
            startActivity(loginintent);
        });

        mAuth=FirebaseAuth.getInstance();
        btnRegister.setOnClickListener(view -> ValidateDataandDoRegister());
    }

    private void ValidateDataandDoRegister() {
        String username=inputUsername.getText().toString().trim();
        String email=inputEmail.getText().toString().trim();
        String password=inputPassword.getText().toString().trim();
        String confirmPassword=inputConfirmPassword.getText().toString().trim();
        if(email.isEmpty()){
            inputEmail.setError("Enter Email Address");
            inputEmail.requestFocus();
            pb.setVisibility(View.GONE);
        }
        else if(email.length()<10){
            inputEmail.setError("Enter valid Email");
            inputEmail.requestFocus();
            pb.setVisibility(View.GONE);
        }
        else if(password.isEmpty()){
            inputPassword.setError("Enter the password");
            inputPassword.requestFocus();
            pb.setVisibility(View.GONE);
        }
        else if(password.length()<8){
            inputPassword.setError("Password should be greater than 8 characters");
            inputPassword.requestFocus();
            pb.setVisibility(View.GONE);
        }
        else if(confirmPassword.isEmpty()){
            inputConfirmPassword.setError("Re-Enter the Password");
            inputConfirmPassword.requestFocus();
            pb.setVisibility(View.GONE);
        }
        else if(confirmPassword.length()<8){
            inputConfirmPassword.setError("Password should be greater than 8 characters");
            inputConfirmPassword.requestFocus();
            pb.setVisibility(View.GONE);
        }
        else if(!password.equals(confirmPassword)){
            inputPassword.setError("Password not matched");
            inputPassword.requestFocus();
            inputConfirmPassword.setError("Password not matched");
            inputConfirmPassword.requestFocus();
            inputPassword.setText("");
            inputConfirmPassword.setText("");
            pb.setVisibility(View.GONE);
        }
        else{
            pb.setVisibility(View.VISIBLE);
            doRegister(username,email,password);
        }
    }

    private void doRegister(String username,String email, String password) {
        pb.setVisibility(View.VISIBLE);
        mAuth.createUserWithEmailAndPassword(email, password).addOnSuccessListener(task -> {
            if(task != null ){
                if(mAuth.getCurrentUser() != null){
                    userID=mAuth.getCurrentUser().getUid();
                }

//                firebaseMethods.registerNewEmail(username,email,password);
                setupFirebaseAuth();
                sendVerificationEmail();
//                firebaseMethods.addNewUser(email, username);
            }

        }).addOnFailureListener(e -> {
            if(e instanceof FirebaseAuthUserCollisionException){
                btnRegister.setEnabled(true);
                inputEmail.setError("Email Already Registered");
                pb.setVisibility(View.GONE);
                inputEmail.requestFocus();
            }
            else{
                btnRegister.setEnabled(true);
                pb.setVisibility(View.GONE);
                Toast.makeText(activity_register.this, "Oops! Something Went wrong", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void sendVerificationEmail() {
        mAuth.getCurrentUser().sendEmailVerification().addOnCompleteListener(task -> {
            if(task != null && task.isSuccessful()){
                btnRegister.setEnabled(true);
                pb.setVisibility(View.GONE);
                Toast.makeText(activity_register.this, "Email has been sent to your email address", Toast.LENGTH_SHORT).show();
                //fixing the bug
                mAuth.signOut();
            }
            else {
                btnRegister.setEnabled(true);
                pb.setVisibility(View.GONE);
                Toast.makeText(getApplicationContext(), "Oops! failed to send verification email",Toast.LENGTH_SHORT).show();
            }
        });
    }


    /*
    ------------------------------------ Firebase ---------------------------------------------
     */

    /**
     * Setup the firebase auth object
     */
    private void setupFirebaseAuth(){
        Log.d(TAG, "setupFirebaseAuth: setting up firebase auth.");

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

        //cannot get into this part of code
        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.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            //1st check: Make sure the username is not already in use
                            if(firebaseMethods.checkIfUsernameExists(username, dataSnapshot)){
                                //to randomly generate key to make sure username is unique
                                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(activity_register.this, "SignUp successful", Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {
                            Toast.makeText(activity_register.this, "unsuccessful", Toast.LENGTH_SHORT).show();
                        }
                    });
                    finish();

                } else {
                    // User is signed out
                    Toast.makeText(activity_register.this, "unsuccessful", Toast.LENGTH_SHORT).show();
                    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);
        }
    }

}

问题原因

错误日志明确指出,在调用FirebaseAuth.AuthStateListener.onAuthStateChanged时,listener对象为null。查看代码逻辑:

  • mAuthListener仅在setupFirebaseAuth()方法中初始化
  • setupFirebaseAuth()是在用户点击注册按钮后的doRegister()方法里才被调用
  • 但Activity的onStart()方法会在页面打开时立即执行,此时mAuthListener还未被初始化,调用mAuth.addAuthStateListener(mAuthListener)就会触发空指针异常。

另外还有一个潜在问题:username变量在onCreate()时获取输入框文本(此时输入框为空),后续在setupFirebaseAuth()中使用的是这个空值,而非用户实际输入的用户名。

修复方案

1. 提前初始化AuthStateListener

将setupFirebaseAuth()的调用移到onCreate()方法中,确保在onStart()执行前mAuthListener已完成初始化:
修改onCreate()方法末尾:

mAuth=FirebaseAuth.getInstance();
setupFirebaseAuth(); // 提前初始化AuthStateListener
btnRegister.setOnClickListener(view -> ValidateDataandDoRegister());

同时删除doRegister()方法中的setupFirebaseAuth();调用。

2. 修正username变量的取值逻辑

在setupFirebaseAuth()的onDataChange方法中,直接从输入框获取最新的用户名,避免使用初始化时的空值:

// 替换原username = username + append;
String inputUsernameStr = inputUsername.getText().toString().trim();
String finalUsername = firebaseMethods.checkIfUsernameExists(inputUsernameStr, dataSnapshot) 
    ? inputUsernameStr + append 
    : inputUsernameStr;

后续存储用户数据时使用finalUsername即可。

3. 优化AuthStateListener逻辑

由于注册成功后会调用sendVerificationEmail()并执行mAuth.signOut(),AuthStateListener会检测到用户登出,此时不需要弹出失败提示,可调整逻辑避免误导用户:

@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
    FirebaseUser user=firebaseAuth.getCurrentUser();
    if (user != null) {
        // 用户已登录,执行数据库存储逻辑
        Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
        // ... 原数据库操作逻辑
    } else {
        // 用户登出,此处无需提示失败,因为是主动登出
        Log.d(TAG, "onAuthStateChanged:signed_out");
    }
}

内容的提问来源于stack exchange,提问作者Nithin reddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:50:27