如何使用异步查询处理检查 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);