简体   繁体   中英

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

I'm developing an android application for college project using Java and Firebase. I want to store the details of faculties working in college like name,email,department etc based on their position. I have created 3 child nodes HOD,Class mentor and lecturers inside Faculties as you can see that in here.

在此处输入图像描述

my problem is when I want to add the members inside any one these child I want to check if that members email ID is exist in any other childs. For example I want to add a member in HOD child.If this members email existed inside Lecturers child it should display Toast user already existed as Lecturer else it should add member inside Lecturer.

I used this code.

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();
    }
});

It works fine but it's lengthy and also it takes time to check.If there is any better solution that would be very helpful.

This is is my code complete code for adding Faculties.

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's queries work on a list of nodes. Since you have a hierarchy, you'll need to fire the same query for each list you have in there, as you're doing today.

As usual when dealing with NoSQL databases, the solution is to model the data in a way that makes the use-case easiest. If you want to search across all members, store a single list of members:

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

With the above structure you only have to execute one query to find all members with a specific email address.


You can either use the above structure to replace the three structures you currently have, or you can use it as an additional structure just for this use-case. Which one to choose depends on the other use-cases in your app, there is no solution that is right for all apps, just the one that works for you.


Enforcing uniques across values as you're doing here, will lead to scalability issues over time, as you:

  1. Need to search across all members, which takes more time as you get more members.
  2. More importantly: you will need to use a transaction to insert new users, to reduce the chances that multiple users claim the same email address at the same time.
  3. This leads to a second scaling problem, as you'll need to run that transaction on the evert-growing /members node.
  4. Finally: a malicious user can bypass the transaction by writing their own code, and still claim any email address.

Ensuring uniqueness on Firebase is only really enforceable if you use those values as the key in a list, so by maintaining a (additional) list of email addresses.

For more on this see:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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