在当前结构中,您可以通过以下查询检查大学名称作为一个值存在的频率/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"
}
保证唯一性已经被讨论了好几次了,所以我建议检查一下这些:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句