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

Firebase注册无法进入OnAuthStateChanged,用户数据无法存入实时数据库

Firebase注册时用户信息存入数据库的问题修复

一、解决启动页面的空指针异常

启动页面时的空指针是因为onStart中尝试添加未初始化的mAuthListener导致的。需要提前初始化监听逻辑,并规范监听的添加/移除时机:

修改activity_register代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ... 原有初始化代码 ...
    mAuth = FirebaseAuth.getInstance();
    // 提前初始化Auth状态监听
    initAuthStateListener();
    btnRegister.setOnClickListener(view -> ValidateDataandDoRegister());
}

// 单独抽离Auth状态监听的初始化逻辑
private void initAuthStateListener() {
    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
                userID = user.getUid();
                // 初始化数据库引用
                setupFirebaseAuth();
                
                myRef.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        String currentUsername = inputUsername.getText().toString().trim();
                        String append = "";
                        // 检查用户名是否已存在
                        if(firebaseMethods.checkIfUsernameExists(currentUsername, dataSnapshot)){
                            append = myRef.push().getKey().substring(3,10);
                            Log.d(TAG, "onDataChange: 用户名已存在,追加随机串: " + append);
                        }
                        String finalUsername = currentUsername + append;
                        
                        // 传入userID调用添加用户方法
                        firebaseMethods.addNewUser(userID, inputEmail.getText().toString().trim(), finalUsername);
                        Toast.makeText(activity_register.this, "注册成功", Toast.LENGTH_SHORT).show();
                        sendVerificationEmail();
                        finish();
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        Toast.makeText(activity_register.this, "数据库操作失败", Toast.LENGTH_SHORT).show();
                        pb.setVisibility(View.GONE);
                    }
                });
            } else {
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
        }
    };
}

// 修改setupFirebaseAuth,仅初始化数据库引用
private void setupFirebaseAuth(){
    Log.d(TAG, "setupFirebaseAuth: 初始化Firebase数据库");
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    myRef = mFirebaseDatabase.getReference();
}

// 规范监听的添加和移除
@Override
public void onStart() {
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

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

二、修复userID为空的问题

原FirebaseMethods中userID在构造函数中获取,无法拿到注册后生成的新用户ID。修改addNewUser方法,直接传入userID参数:

修改FirebaseMethods类:

// 修改addNewUser方法,新增userID参数
public void addNewUser(String userID, String email, String username){
    User user = new User(email, username);
    if(userID != null){
        myRef.child(mContext.getString(R.string.dbname_users))
                .child(userID)
                .setValue(user).addOnSuccessListener(unused -> {
                    Log.d(TAG, "用户信息已存入数据库");
                    Toast.makeText(mContext, "用户信息保存成功", Toast.LENGTH_SHORT).show();
                }).addOnFailureListener(e -> {
                    Log.d(TAG, "用户信息保存失败: " + e.getMessage());
                    Toast.makeText(mContext, "保存失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                });

        UserAccountSettings settings = new UserAccountSettings(username, username);
        myRef.child(mContext.getString(R.string.dbname_user_account_settings))
                .child(userID)
                .setValue(settings);
    } else {
        Log.d(TAG, "userID为空,无法保存用户信息");
        Toast.makeText(mContext, "用户ID无效,无法保存信息", Toast.LENGTH_SHORT).show();
    }
}

// 修复checkIfUsernameExists的遍历逻辑,检查所有用户的用户名
public boolean checkIfUsernameExists(String username, DataSnapshot dataSnapshot){
    for (DataSnapshot ds : dataSnapshot.child(mContext.getString(R.string.dbname_users)).getChildren()){
        User user = ds.getValue(User.class);
        if(user != null && user.getUsername() != null){
            if(StringManipulation.expandUsername(user.getUsername()).equals(username)){
                return true;
            }
        }
    }
    return false;
}

三、调整注册流程,确保监听触发

修改doRegister方法,移除手动获取userID和调用setupFirebaseAuth的逻辑,让Auth状态监听自动处理注册成功后的流程:

private void doRegister(String username,String email, String password) {
    pb.setVisibility(View.VISIBLE);
    btnRegister.setEnabled(false); // 防止重复点击
    mAuth.createUserWithEmailAndPassword(email, password)
            .addOnFailureListener(e -> {
                pb.setVisibility(View.GONE);
                btnRegister.setEnabled(true);
                if(e instanceof FirebaseAuthUserCollisionException){
                    inputEmail.setError("该邮箱已注册");
                    inputEmail.requestFocus();
                } else {
                    Toast.makeText(activity_register.this, "注册失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
}

四、其他优化

  • 给sendVerificationEmail添加空判断,避免空指针:
private void sendVerificationEmail() {
    FirebaseUser currentUser = mAuth.getCurrentUser();
    if(currentUser != null){
        currentUser.sendEmailVerification().addOnCompleteListener(task -> {
            btnRegister.setEnabled(true);
            pb.setVisibility(View.GONE);
            if(task.isSuccessful()){
                Toast.makeText(activity_register.this, "验证邮件已发送至你的邮箱", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getApplicationContext(), "发送验证邮件失败: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    } else {
        pb.setVisibility(View.GONE);
        btnRegister.setEnabled(true);
        Toast.makeText(this, "用户未登录,无法发送验证邮件", Toast.LENGTH_SHORT).show();
    }
}

内容的提问来源于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.15 12:55:18