如何使用异步查询处理检查 Firebase 中是否存在具有值的条目
How to check whether an entry with a value exists in Firebase with asynchronous query handling
我有以下 Firebase 数据库。
我想查询数据库“Ratings”,这样每个具有特定 orderID
的条目都应该 returned。为此,我尝试结合 Firebase API 的异步处理(在此视频 https://www.youtube.com/watch?v=OvDZVV5CbQg&ab_channel=AlexMamo) with the query approach (explained here 中进行了解释)。
这里可以看到我的Java片段的代码(数据库全名URL由于隐私原因没有给出):
public class FR_Rating extends Fragment implements View.OnClickListener {
private int orderId =-1;
private FragmenRateBinding binding;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmenRateBinding.inflate(inflater, container, false);
orderId = FR_RatingArgs.fromBundle(getArguments()).getOrderId();
// Set onclick Listeners to the buttoms
binding.rateButton.setOnClickListener(this);
return binding.getRoot();
}
@Override
public void onClick(View view) {
float numberOfStars = binding.ratingBar.getRating();
/*
Read data from the Firebase DB
*/
long currentTimeMillis = System.currentTimeMillis();
SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yy");
sdf1.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm (dd.MM.yy)");
sdf2.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
String entryIdPrefix = "table_" + MainActivity.tableNumber + "_rating_" + MainActivity.ratingNumberOfTheSession;
Item_FirebaseDB_Rating currentRating = new Item_FirebaseDB_Rating(MainActivity.ratingNumberOfTheSession, numberOfStars, orderId, MainActivity.tableNumber,currentTimeMillis, sdf2.format(new Date()));
DatabaseReference rootRef;
DatabaseReference ratingRef;
ArrayList<String> ratingList;
rootRef = FirebaseDatabase.getInstance("https://...").getReference();
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(Integer.toString(orderId));
ratingList = new ArrayList<>();
readDataFirebase(new FirebaseCallback() {
@Override
public void onCallBack(List<String> list) {
Log.e("LogTag", "list.toString(): " + list.toString());
if (ratingList.size()==0) {
Log.e("LogTag", "Item will be rated");
writeDataIntoFirebaseDB(currentRating, entryIdPrefix);
}
if (ratingList.size()>0) {
Log.e("LogTag", "Item has already been rated");
}
}
}, ratingList, query, Integer.toString(orderId));
Navigation.findNavController(getView()).navigate(FR_RatingDirections.actionFRRatingToFRMyMenu());
}//End method onClick
private void readDataFirebase (FirebaseCallback firebaseCallback, ArrayList ratingList,Query query, String currentOrderID ) {
ValueEventListener valueEventListener = new ValueEventListener() {
int numberOfChildren =0;
@Override
public void onDataChange( DataSnapshot dataSnapshot) {
for(DataSnapshot ds: dataSnapshot.getChildren()) {
numberOfChildren++;
String itemName = ds.child("orderID").getValue(Long.class).toString();
if (itemName.equals(currentOrderID)) {
ratingList.add(itemName);
}
}
Log.e("LogTag", "Method readDataFirebase - numberOfChildren: " + numberOfChildren);
firebaseCallback.onCallBack (ratingList);
}
@Override
public void onCancelled( DatabaseError error) {
}
};
query.addListenerForSingleValueEvent(valueEventListener);
}
private interface FirebaseCallback {
void onCallBack(List<String> list);
}
public void writeDataIntoFirebaseDB (Item_FirebaseDB_Rating currentRating, String entryIdPrefix) {
MainActivity.ratingNumberOfTheSession++;
//Call of a static method in the class HelpFunctions that just writes the data into the Firebase Database
boolean internetConnectionWasAvailableWhileWriting = HelpFunctions.writeDataIntoFirebaseDB(currentRating, DataBaseEntries.FIREBASE_TABLE_RATINGS, entryIdPrefix);
}
}//End class Fragment
不幸的是,即使特定条目存在,我总是得到一个空的查询结果。例如,我想 return 属性“orderID”为 76 的条目。但是我在方法 readDataFirebase
.
中得到一个空结果
有人能告诉我,如何正确执行此操作吗?
您的 orderID
字段存储为数字,但您试图将其与此处的字符串进行比较:
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(Integer.toString(orderId));
Firebase 中的比较对类型敏感,因此字符串 "76"
与数字 76
不同,这就是您得不到结果的原因。
解决方案是将值作为数字传递给数据库:
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(orderId);
我有以下 Firebase 数据库。
我想查询数据库“Ratings”,这样每个具有特定 orderID
的条目都应该 returned。为此,我尝试结合 Firebase API 的异步处理(在此视频 https://www.youtube.com/watch?v=OvDZVV5CbQg&ab_channel=AlexMamo) with the query approach (explained here
这里可以看到我的Java片段的代码(数据库全名URL由于隐私原因没有给出):
public class FR_Rating extends Fragment implements View.OnClickListener {
private int orderId =-1;
private FragmenRateBinding binding;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmenRateBinding.inflate(inflater, container, false);
orderId = FR_RatingArgs.fromBundle(getArguments()).getOrderId();
// Set onclick Listeners to the buttoms
binding.rateButton.setOnClickListener(this);
return binding.getRoot();
}
@Override
public void onClick(View view) {
float numberOfStars = binding.ratingBar.getRating();
/*
Read data from the Firebase DB
*/
long currentTimeMillis = System.currentTimeMillis();
SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yy");
sdf1.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm (dd.MM.yy)");
sdf2.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
String entryIdPrefix = "table_" + MainActivity.tableNumber + "_rating_" + MainActivity.ratingNumberOfTheSession;
Item_FirebaseDB_Rating currentRating = new Item_FirebaseDB_Rating(MainActivity.ratingNumberOfTheSession, numberOfStars, orderId, MainActivity.tableNumber,currentTimeMillis, sdf2.format(new Date()));
DatabaseReference rootRef;
DatabaseReference ratingRef;
ArrayList<String> ratingList;
rootRef = FirebaseDatabase.getInstance("https://...").getReference();
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(Integer.toString(orderId));
ratingList = new ArrayList<>();
readDataFirebase(new FirebaseCallback() {
@Override
public void onCallBack(List<String> list) {
Log.e("LogTag", "list.toString(): " + list.toString());
if (ratingList.size()==0) {
Log.e("LogTag", "Item will be rated");
writeDataIntoFirebaseDB(currentRating, entryIdPrefix);
}
if (ratingList.size()>0) {
Log.e("LogTag", "Item has already been rated");
}
}
}, ratingList, query, Integer.toString(orderId));
Navigation.findNavController(getView()).navigate(FR_RatingDirections.actionFRRatingToFRMyMenu());
}//End method onClick
private void readDataFirebase (FirebaseCallback firebaseCallback, ArrayList ratingList,Query query, String currentOrderID ) {
ValueEventListener valueEventListener = new ValueEventListener() {
int numberOfChildren =0;
@Override
public void onDataChange( DataSnapshot dataSnapshot) {
for(DataSnapshot ds: dataSnapshot.getChildren()) {
numberOfChildren++;
String itemName = ds.child("orderID").getValue(Long.class).toString();
if (itemName.equals(currentOrderID)) {
ratingList.add(itemName);
}
}
Log.e("LogTag", "Method readDataFirebase - numberOfChildren: " + numberOfChildren);
firebaseCallback.onCallBack (ratingList);
}
@Override
public void onCancelled( DatabaseError error) {
}
};
query.addListenerForSingleValueEvent(valueEventListener);
}
private interface FirebaseCallback {
void onCallBack(List<String> list);
}
public void writeDataIntoFirebaseDB (Item_FirebaseDB_Rating currentRating, String entryIdPrefix) {
MainActivity.ratingNumberOfTheSession++;
//Call of a static method in the class HelpFunctions that just writes the data into the Firebase Database
boolean internetConnectionWasAvailableWhileWriting = HelpFunctions.writeDataIntoFirebaseDB(currentRating, DataBaseEntries.FIREBASE_TABLE_RATINGS, entryIdPrefix);
}
}//End class Fragment
不幸的是,即使特定条目存在,我总是得到一个空的查询结果。例如,我想 return 属性“orderID”为 76 的条目。但是我在方法 readDataFirebase
.
有人能告诉我,如何正确执行此操作吗?
您的 orderID
字段存储为数字,但您试图将其与此处的字符串进行比较:
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(Integer.toString(orderId));
Firebase 中的比较对类型敏感,因此字符串 "76"
与数字 76
不同,这就是您得不到结果的原因。
解决方案是将值作为数字传递给数据库:
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(orderId);