[英]Check value already exists or not in Firebase?
在您當前的結構中,您可以使用如下查詢檢查大學名稱作為/Universities
下的值存在的頻率:
String name = "Comsats";
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Universities");
ref.orderByValue().equalTo(name).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i("Firebase", "There are "+dataSnapshot.getChildrenCount()+" universities named "+name);
for (DataSnapshot universitySnapshot: dataSnapshot.getChildren()) {
Log.i("Firebase", universitySnapshot.getKey+": "+universitySnapshot.getValue(String.class));
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
或者只是為了檢查它是否存在,這會更簡單/更快:
ref.orderByValue().equalTo(name).limitToFirst(1).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Log.i("Firebase", "University "+name+" already exists");
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
但是,如果您使用上述方法添加大學,則最終會出現競爭條件。 當一個客戶端檢查名稱是否已經存在時,另一個客戶端可能正在添加它。 由於不能保證按照您希望的順序進行操作,因此您最終仍可能得到兩所同名大學。
防止這種情況的唯一方法是使用大學名稱作為節點的鍵* 而不是值。 你的結構會變成:
"Universities": {
"University of Haripu": true,
"Comsats": true,
"UET": true
}
節點鍵在某個位置保證是唯一的,因為無法插入具有相同名稱的第二個子節點。 因此,通過這種結構,您可以自動保證數據結構中的唯一性要求。
true
值在上述結構中沒有特定含義,只是因為 Firebase 無法存儲沒有值的鍵。 如果你有一個更有意義的值,你也可以使用它。 事實上,你可能不得不這樣做......
Firebase 有一些字符不允許出現在節點鍵中,而這些字符允許出現在值中。 如果您的值可能有這樣的值,您將需要從用戶輸入的值到您為大學存儲的密鑰執行一些編碼。
兩種常見的編碼是:
第一種方法導致更易識別的鍵,所以我將在這里使用它。 在實踐中,第二種方法通常在代碼中更好、更簡單,因為現在散列是非常標准的功能,而其他編碼可能會針對您的用例或 Firebase 進行自定義。
在這兩種情況下,您都需要存儲用戶輸入的實際值。 因此,如果鍵不允許使用空格和大寫字符(它們都是允許的,所以這只是一個說明性示例),您最終會得到:
"Universities": {
"universityofharipu": "University of Haripu",
"comsats": "Comsats",
"uet": "UET"
}
保證唯一性之前已經講過很多次了,所以我建議看看這些:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.