繁体   English   中英

检查一个值是否存在于子 Firebase Android 中的数据库中

[英]Check if a value exist in more then on child Firebase Database in Android

我正在使用 Java 和 Firebase 为大学项目开发 android 应用程序。 我想根据他们的 position 存储在大学工作的学院的详细信息,例如名称、email、部门等。 我在 Faculties 中创建了 3 个子节点 HOD、Class 导师和讲师,您可以在此处看到。

在此处输入图像描述

我的问题是,当我想在这些孩子中添加成员时,我想检查该成员 email ID 是否存在于任何其他孩子中。 例如,我想在 HOD 子项中添加一个成员。如果此成员 email 存在于 Lecturers 子项中,则应显示 Toast 用户已作为讲师存在,否则应在讲师中添加成员。

我使用了这段代码。

post = "HOD";
    databaseReference.child(post).orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()){
            Toast.makeText(MainActivityAddFaculty.this, "User already exist in "+post, Toast.LENGTH_SHORT).show();
        } else {
            post = "Class mentor";
            databaseReference.child(post).orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()){
                        Toast.makeText(MainActivityAddFaculty.this, "User already exist in "+post, Toast.LENGTH_SHORT).show();
                    } else {
                        post = "Lecturer";
                        databaseReference.child(post).orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                if (dataSnapshot.exists()){
                                    Toast.makeText(MainActivityAddFaculty.this, "User already exist in "+post, Toast.LENGTH_SHORT).show();
                                } else {
                                    checkData();
                                }
                            }

                            @Override
                            public void onCancelled(@NonNull DatabaseError databaseError) {
                                Toast.makeText(MainActivityAddFaculty.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Toast.makeText(MainActivityAddFaculty.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });

        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Toast.makeText(MainActivityAddFaculty.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

它工作正常,但它很长,而且需要时间来检查。如果有任何更好的解决方案会非常有帮助。

这是我添加院系的完整代码。

public class MainActivityAddFaculty extends AppCompatActivity {
    private TextInputLayout addName, addEmail;
    private TextInputEditText addEditName, addEditEmail;
    private Button addBtn;

    private Spinner addPositionSpinner,addDeptSpinner,addYearSpinner;
    private TextView addPosition,addDept,addYear;

    private String sDept = "Select department",sPost = "Select position",sYear = "Select year";
    private String position,department,year,post;
    private boolean b = false;

    private FirebaseDatabase firebaseDatabase;
    private FirebaseStorage firebaseStorage;
    private DatabaseReference databaseReference,databaseReference2;
    private StorageReference storageReference;
    LoadingDialog loadingDialog;

    private String facultyID;
    private String name,email;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_faculty);
        setTitle("Add Hod");

        assert getSupportActionBar() != null;
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        addName = findViewById(R.id.addFName);
        addEmail = findViewById(R.id.addFEmail);
        addEditName = findViewById(R.id.addFEditName);
        addEditEmail = findViewById(R.id.addFEditEmail);
        addBtn = findViewById(R.id.addFBtn);

        addPositionSpinner = findViewById(R.id.addFPositionSpinner);
        addPosition = findViewById(R.id.addFPosition);
        addDeptSpinner = findViewById(R.id.addFDepartmentSpinner);
        addDept = findViewById(R.id.addFDepartment);
        addYearSpinner = findViewById(R.id.addFYearSpinner);
        addYear = findViewById(R.id.addFYear);

        addDeptSpinner.setVisibility(View.GONE);
        addYearSpinner.setVisibility(View.GONE);
        addDept.setVisibility(View.GONE);
        addYear.setVisibility(View.GONE);

        firebaseDatabase = FirebaseDatabase.getInstance();
        databaseReference = firebaseDatabase.getReference("FACULTIES");

        facultyID = databaseReference.push().getKey();

        loadingDialog = new LoadingDialog(MainActivityAddFaculty.this);
        //selectPosition();

        //TODO:Select position
        List<String> categories = new ArrayList<>();
        categories.add(0,"Select position");
        categories.add("HOD");
        categories.add("Class mentor");
        categories.add("Lecturer");

        ArrayAdapter<String> dataAdapter;
        dataAdapter = new  ArrayAdapter(this,android.R.layout.simple_spinner_item,categories);

        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        addPositionSpinner.setAdapter(dataAdapter);
        addPositionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                addPosition.setText(parent.getSelectedItem().toString());
                test();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                Toast.makeText(MainActivityAddFaculty.this, "Select a position", Toast.LENGTH_SHORT).show();
            }
        });


        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                name = addEditName.getText().toString().trim();
                email = addEditEmail.getText().toString().trim();

                if (TextUtils.isEmpty(name)) {
                    Toast.makeText(MainActivityAddFaculty.this, "Enter name", Toast.LENGTH_SHORT).show();
                }else  {
                    if (TextUtils.isEmpty(email)) {
                        Toast.makeText(MainActivityAddFaculty.this, "Enter email.", Toast.LENGTH_SHORT).show();
                    } else {
                        checkData();
                    }
                }
            }
        });
    }

    private void test(){
        position = addPositionSpinner.getSelectedItem().toString();

        if (position.equals(sPost)){
            addDeptSpinner.setVisibility(View.GONE);
            addYearSpinner.setVisibility(View.GONE);
            addDept.setVisibility(View.GONE);
            addYear.setVisibility(View.GONE);
        }else if (position.equals("HOD")){
            addDeptSpinner.setVisibility(View.VISIBLE);
            addYearSpinner.setVisibility(View.GONE);
            addDept.setVisibility(View.VISIBLE);
            addYear.setVisibility(View.GONE);
        } else if (position.equals("Class mentor")){
            addDeptSpinner.setVisibility(View.VISIBLE);
            addDept.setVisibility(View.VISIBLE);
            addYearSpinner.setVisibility(View.VISIBLE);
            addYear.setVisibility(View.VISIBLE);
        } else if (position.equals("Lecturer")){
            addDeptSpinner.setVisibility(View.GONE);
            addYearSpinner.setVisibility(View.GONE);
            addDept.setVisibility(View.GONE);
            addYear.setVisibility(View.GONE);
        } else {
            addDeptSpinner.setVisibility(View.GONE);
            addYearSpinner.setVisibility(View.GONE);
            addDept.setVisibility(View.GONE);
            addYear.setVisibility(View.GONE);
        }
}

    private void checkData(){
        position = addPositionSpinner.getSelectedItem().toString();
        department = addDeptSpinner.getSelectedItem().toString();
        year = addYearSpinner.getSelectedItem().toString();

        if (position.equals(sPost)){
            Toast.makeText(this, "Select position", Toast.LENGTH_SHORT).show();
        } else if (position.equals("HOD")){
                        if (department.equals(sDept)){
                            Toast.makeText(MainActivityAddFaculty.this, "Select department.", Toast.LENGTH_SHORT).show();
                        } else {
                            AddHOD addHOD = new AddHOD(name,position,department,email,facultyID);
                            databaseReference.child(position).child(facultyID).setValue(addHOD).addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(Void aVoid) {
                                    Toast.makeText(MainActivityAddFaculty.this, "Faculty added successfully", Toast.LENGTH_SHORT).show();
                                }
                            }).addOnFailureListener(new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    Toast.makeText(MainActivityAddFaculty.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
        }else if (position.equals("Class mentor")){
                //add Class mentor process started
                if (!department.equals(sDept)){
                    if (!year.equals(sYear)) {
                        AddClassMentor addClassMentor = new AddClassMentor(name, position, department, year, email, facultyID);
                        databaseReference.child(position).child(facultyID).setValue(addClassMentor).addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                Toast.makeText(MainActivityAddFaculty.this, "Faculty added successfully", Toast.LENGTH_SHORT).show();
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Toast.makeText(MainActivityAddFaculty.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });
                    }else {
                        Toast.makeText(this, "Select year.", Toast.LENGTH_SHORT).show();
                    }
                    } else {
                    Toast.makeText(this, "Select department", Toast.LENGTH_SHORT).show();
                    }
        } else if (position.equals("Lecturer")){
            AddLecturer addLecturer = new AddLecturer(name,position,email,facultyID);
            databaseReference.child(position).child(facultyID).setValue(addLecturer).addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    Toast.makeText(MainActivityAddFaculty.this, "Faculty added successfully", Toast.LENGTH_SHORT).show();
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(MainActivityAddFaculty.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            Toast.makeText(this, "Entry is pending.", Toast.LENGTH_SHORT).show();
        }
    }
}

Firebase 的查询适用于节点列表 由于您有一个层次结构,因此您需要为其中的每个列表触发相同的查询,就像您今天所做的那样。

像往常一样处理 NoSQL 数据库时,解决方案是以使用例最简单的方式对 model 数据进行处理。 如果要搜索所有成员,请存储一个成员列表:

"members": {
  "$memberid": {
    "email": "membersemail@institute.edu",
    "memberType": "Class mentor" // or "HOD" or "Lecturer"
  }
}

使用上述结构,您只需执行一个查询即可找到具有特定 email 地址的所有成员。


您可以使用上述结构来替换您当前拥有的三个结构,可以将其用作此用例的附加结构。 选择哪一个取决于您的应用程序中的其他用例,没有适合所有应用程序的解决方案,只有适合您的解决方案。


正如您在此处所做的那样跨值强制执行唯一性,随着时间的推移会导致可伸缩性问题,因为您:

  1. 需要搜索所有成员,当您获得更多成员时,这需要更多时间。
  2. 更重要的是:您将需要使用事务来插入新用户,以减少多个用户同时声明同一个 email 地址的机会。
  3. 这会导致第二个扩展问题,因为您需要在不断增长的/members节点上运行该事务。
  4. 最后:恶意用户可以通过编写自己的代码绕过交易,并且仍然声称任何 email 地址。

确保 Firebase 的唯一性只有在您使用这些值作为列表中的键时才真正可执行,因此通过维护 email 地址的(附加)列表。

有关这方面的更多信息,请参阅:

暂无
暂无

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

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