I have the following Firebase database.
I would like to query the database "Ratings" sucht that every entry with a certain orderID
should be returned. For this I tried to combine the asynchronous handling of the Firebase API (explained in this video https://www.youtube.com/watch?v=OvDZVV5CbQg&ab_channel=AlexMamo) with the query approach (explained here Checking if a particular value exists in the Firebase database).
Here you can see the code of my Java Fragment (the full name of the database URL is not given due to privacy reasons):
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
Unfortunately I always get an empty result of the query, even if the particual entry exists. For example I would like to return the entry whose attribute ´orderID´ is 76. But I get an empty result in the method readDataFirebase
.
Can some tell me, what to do this properly?
CodePudding user response:
Your orderID
field is stored as a number, yet you're trying to compare it to a string here:
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(Integer.toString(orderId));
Comparisons in Firebase are type-sensitive, so a string "76"
is not the same as the number 76
, which is why you get no results.
The solution is to pass the value to the database as a number:
Query query = rootRef.child("Ratings").orderByChild("orderID").equalTo(orderId);