Home > Mobile >  How to check whether an entry with a value exists in Firebase with asynchronous query handling
How to check whether an entry with a value exists in Firebase with asynchronous query handling

Time:12-14

I have the following Firebase database. enter image description here

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);
  • Related