簡體   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