我正在使用Firebase数据库来存储用户的报告。每个用户只能提交10份不同的报告。
在下面的例子中,我们有一个名为“Jasna Kuljancic”的用户,他提交了3份报告。
我的问题是如何检查用户是否已提交特定报告?
我必须检查“location”,“mode”,“spinnerOne”的值并将它们与用户刚刚输入的内容进行比较,如果它已经存在,那么就不要添加到数据库中,如果是,那么添加它。这是我的尝试:
public void checkifentryExistofNot() {
uniqueID = mDatabaseReference.push().getKey();
fullname = “Jasna Kuljancic”;
CATEGORY = “Clinical First”);
final Report subreport = new Report(SELECTED_LOCATION,
locationEditText.getText().toString(),
modeEditText.getText().toString(),
Integer.parseInt(dateEditText.getText().toString()));
mDatabaseReference.child("Students Reports").child(fullname).child(CATAGORY).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
int numberofCount = (int) dataSnapshot.getChildrenCount();
if (numberofCount == 0) {
mDatabaseReference.child("Students Reports").child(fullname).child(CATAGORY).child(uniqueID).setValue(subreport);
}
if (numberofCount != 0) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
Report datareports = child.getValue(Report.class);
thelocation = datareports.getLocation();
themode = datareports.getMode();
if (thelocation.equals(locationEditText.getText().toString()) && themode.equals(modeEditText.getText().toString())) {
break;
} else {
mDatabaseReference.child("Students Reports").child(fullname).child(CATAGORY).child(uniqueID).setValue(subreport);
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
我的解决方案的问题是for循环将检查每个报告,并且在每种情况下它将添加或不添加新报告,但这将在存在的报告数量上发生,并且它应该只执行一次。
换句话说,如果我们有3个条目,并且每次它不存在,它将提交报告3次(这不是很糟糕)。但是如果它检查第一个报告并且它确实存在,那么循环将退出,因为我在那里有一个“中断”(这很好)但是让我们说第二个报告是一个重复的报告,它本来就是将它添加到数据库,因为第一个条目不是重复。希望我明白这一点。
任何帮助将不胜感激。我觉得我已经完成了这个,应该有一个更快的方法来做到这一点。
答案 0 :(得分:1)
Firebase查询只能按单个属性进行排序/过滤。因此Firebase中没有WHERE
子句。你应该怎么做,就是结合一个名为location_mode_spinnerOne
的复合值。您的数据库结构应如下所示:
Firebase-root
|
-- Students Reports
|
-- Jasna Kuljancic
|
-- Clinical First
|
-- -KuVRQ4OjdfKXCNdLWzb
|
--- data: 3939393
|
--- location: "fifififi"
|
--- mode: "ododododo"
|
--- spinnerOne: "Asylum Hill Family Clinic"
|
--- location_mode_spinnerOne: "fifififi_ododododo_Asylum Hill Family Clinic"
正如您可能看到的,我为每个特定类别添加了新的复合值location_mode_spinnerOne
。这意味着您可以根据此新location_mode_spinnerOne
字段查询Firebase数据库。假设上述数据库结构正确,请使用以下代码:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference categoryRef = rootRef.child("Students Reports").child(fullname).child(CATAGORY);
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String searchedText = "fifififi";
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String location_mode_spinnerOne = ds.child("location_mode_spinnerOne").getValue(String.class);
if(!location_mode_spinnerOne.contains(searchedText)) {
categoryRef.child(uniqueID).setValue(subreport);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
categoryRef.addListenerForSingleValueEvent(eventListener);
我为您提供了搜索fifififi
关键字的示例。 searchedText
文本将是用户输入的确切搜索文本。
为了更好地理解,我建议您看到tutorial。
答案 1 :(得分:1)
dataSnapshot.getChildrenCount()它会显示孩子的总数。 您所要做的就是让Model类在对象中保存您的值,并在编辑时检查对象是否具有相同的数据,然后不要更新数据,如果不同则更新数据。
答案 2 :(得分:1)
这个问题有两种解决方法。我认为对于第一种方法,你已经很清楚如何做到这一点。只缺少的是分离[a]验证报告唯一性的顺序动作和[b]将对象添加到数据库。按下按钮可能会添加报告。我建议,按下按钮获取所需表格的数据快照。由于报告的唯一性受到单个用户的限制,因此可以获取单个用户的所有报告。然后简单地将目标报告与获取的报告进行比较并相应地进行。如果是唯一的,则添加或报告重复。差异(w.r.t你的代码)不会附加事件监听器。我认为您的代码处理与Firebase数据一致。在这里,您将获得数据转储,比较它然后更新它。
另一种方法是利用Firebase提供的规则。基本上,它与第一种方法相同,但所有工作都由firebase完成。以下是仅向Firebase插入唯一用户名的代码:
"usernames": {
"$usernameid": {
".read": "auth != null",
".write": "auth != null && (!data.exists() || !newData.exists())"
}
}
在您的问题的上下文中,您可以根据三个值检查报告的唯一性。添加所有三个值的规则。这将允许为每个用户插入唯一报告。但请务必正确添加规则,因为规则的范围必须是针对单个用户的,而不是针对数据库中的所有报告。