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

向Firebase Database提交UserData时重复创建大量节点的问题

问题描述

使用Firebase Auth实现邮箱密码认证,同时向Firebase Database提交用户数据时,点击一次提交按钮会生成大量重复的用户节点,需求是用户注册时创建带有唯一Push ID的新用户节点,运行过程无报错。

UserRegistration.java 代码

public class UserRegistration extends AppCompatActivity {
    EditText name, school, address, standard, contact, password, conf_password, email;
    Button submit;
    String regex = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$";
    ProgressDialog progressDialog;

    FirebaseAuth mAuth;
    FirebaseUser mUser;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_student_registration);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        name = findViewById(R.id.name);
        standard = findViewById(R.id.standard);
        school = findViewById(R.id.school);
        address = findViewById(R.id.address);
        contact = findViewById(R.id.contact);
        email = findViewById(R.id.email);
        password = findViewById(R.id.password);
        conf_password = findViewById(R.id.conf_password);
        submit = findViewById(R.id.registration_button);
        progressDialog = new ProgressDialog(this);
        mAuth = FirebaseAuth.getInstance();
        mUser = mAuth.getCurrentUser();

        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PerformAuth();
            }
        });
    }

    private void PerformAuth() {
        String input_name = name.getText().toString();
        String input_standard = standard.getText().toString();
        String input_school = school.getText().toString();
        String input_address = address.getText().toString();
        String input_contact = contact.getText().toString();
        String input_email = email.getText().toString();
        String input_password = password.getText().toString();
        String input_conf_password = conf_password.getText().toString();

        if(input_name.isEmpty()){
            name.requestFocus();
            name.setError("Enter Your Name");
        } else if (input_standard.isEmpty()) {
            standard.requestFocus();
            standard.setError("Enter Your Class");
        } else if (input_school.isEmpty()) {
            school.setError("Enter Name of Your School");
            school.requestFocus();
        } else if (input_address.isEmpty()) {
            address.requestFocus();
            address.setError("Enter your Address");
        } else if (!input_email.matches(regex)) {
            email.requestFocus();
            email.setError("Enter Valid Email");
        } else if (input_password.isEmpty() || input_password.length()<6) {
            password.requestFocus();
            password.setError("Enter Valid Password (length must be greater than 6)");
        } else if (!input_password.equals(input_conf_password)) {
            conf_password.requestFocus();
            conf_password.setError("Password not matched");
        }
        else if (input_contact.isEmpty() || input_contact.length()>10) {
            contact.requestFocus();
            contact.setError("Enter valid Contact Number");
        }
        else {
            progressDialog.setMessage("Please wait while Registering...");
            progressDialog.setTitle("Registration");
            progressDialog.setCanceledOnTouchOutside(false);
            progressDialog.show();

            UserDetails userDetails = new UserDetails(input_name,input_standard,input_school,input_address,input_email,input_password,input_contact);
            DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("User");
            databaseReference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    databaseReference.push().setValue(userDetails);
                }
                @Override
                public void onCancelled(@NonNull DatabaseError error) {}
            });

            mAuth.createUserWithEmailAndPassword(input_email,input_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()){
                        progressDialog.dismiss();
                        SendUserToNextActivity();
                        Toast.makeText(UserRegistration.this, "Registration Successful", Toast.LENGTH_SHORT).show();
                    }else {
                        progressDialog.dismiss();
                        Toast.makeText(UserRegistration.this, ""+task.getException(), Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

    private void SendUserToNextActivity() {
        Intent intent = new Intent(UserRegistration.this,User_Login.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
}

UserDetails.java 代码

package com.gov.thecoachinginstitute;

public class UserDetails {
    String Name,Standard,School,Address,Email,Password,Contact;

    public UserDetails(String name, String standard, String school, String address, String email, String password, String contact) {
        Name = name;
        Standard = standard;
        School = school;
        Address = address;
        Email = email;
        Password = password;
        Contact = contact;
    }

    public String getName() { return Name; }
    public String getStandard() { return Standard; }
    public String getSchool() { return School; }
    public String getAddress() { return Address; }
    public String getEmail() { return Email; }
    public String getPassword() { return Password; }
    public String getContact() { return Contact; }
}

问题截图

重复节点截图1
重复节点截图2

解决方案

问题根源

代码中使用addValueEventListener监听User节点的数据变化,每次调用push().setValue(userDetails)写入新数据后,会触发onDataChange回调,导致重复执行写入操作,循环往复生成大量重复节点。此外,当前逻辑在Auth创建用户之前就写入数据库,可能出现Auth失败但数据已写入的异常情况。

修正步骤

  1. 移除不必要的ValueEventListener,直接调用push().setValue()写入数据;
  2. 将数据库写入逻辑移至Auth创建用户成功的回调中,确保只有Auth成功后才保存用户数据。

修正后的PerformAuth方法代码

private void PerformAuth() {
    String input_name = name.getText().toString();
    String input_standard = standard.getText().toString();
    String input_school = school.getText().toString();
    String input_address = address.getText().toString();
    String input_contact = contact.getText().toString();
    String input_email = email.getText().toString();
    String input_password = password.getText().toString();
    String input_conf_password = conf_password.getText().toString();

    if(input_name.isEmpty()){
        name.requestFocus();
        name.setError("Enter Your Name");
    } else if (input_standard.isEmpty()) {
        standard.requestFocus();
        standard.setError("Enter Your Class");
    } else if (input_school.isEmpty()) {
        school.setError("Enter Name of Your School");
        school.requestFocus();
    } else if (input_address.isEmpty()) {
        address.requestFocus();
        address.setError("Enter your Address");
    } else if (!input_email.matches(regex)) {
        email.requestFocus();
        email.setError("Enter Valid Email");
    } else if (input_password.isEmpty() || input_password.length()<6) {
        password.requestFocus();
        password.setError("Enter Valid Password (length must be greater than 6)");
    } else if (!input_password.equals(input_conf_password)) {
        conf_password.requestFocus();
        conf_password.setError("Password not matched");
    }
    else if (input_contact.isEmpty() || input_contact.length()>10) {
        contact.requestFocus();
        contact.setError("Enter valid Contact Number");
    }
    else {
        progressDialog.setMessage("Please wait while Registering...");
        progressDialog.setTitle("Registration");
        progressDialog.setCanceledOnTouchOutside(false);
        progressDialog.show();

        UserDetails userDetails = new UserDetails(input_name,input_standard,input_school,input_address,input_email,input_password,input_contact);
        DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("User");

        mAuth.createUserWithEmailAndPassword(input_email,input_password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()){
                    // Auth成功后再写入数据库
                    databaseReference.push().setValue(userDetails);
                    progressDialog.dismiss();
                    SendUserToNextActivity();
                    Toast.makeText(UserRegistration.this, "Registration Successful", Toast.LENGTH_SHORT).show();
                }else {
                    progressDialog.dismiss();
                    Toast.makeText(UserRegistration.this, ""+task.getException(), Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

额外优化建议

  • 不建议在数据库中存储明文密码,Firebase Auth已经负责密码管理,无需重复存储;
  • 可以使用Firebase Auth生成的用户UID作为数据库节点键,替代Push ID,更便于关联用户与数据:
    // 替换push()为用户UID
    String userId = mAuth.getCurrentUser().getUid();
    databaseReference.child(userId).setValue(userDetails);
    

内容的提问来源于stack exchange,提问作者Dhananjay Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:17:03