1

I am using the Firebase Realtime database and I constructed a query for the node "Orders" which should return all items whole attribute "orderID" is equal to 2. In my database I have currently 3 items that match this query, meaning that they have the "orderID" 2. However, my query returns a random number of matching items (I checked that by using LogTag). Sometimes it returns nothing, sometimes it returns just the first matching item and sometimes it returns all items. The very strange thing is this randomness. I always execute the same code. I don't understand why it is not returning all of them as I use the loop for (DataSnapshot ds: dataSnapshot.getChildren()) to iterate over all items that should match the query. Any ideas on why this is happening and how I can tackle this problem?

DatabaseReference rootRef_Firebase = FirebaseDatabase.getInstance(FIREBASE_URL).getReference();
rootRef_Firebase
    .child("Orders")
    .orderByChild("oderID")
    .equalTo(2)
    .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            for (DataSnapshot ds: dataSnapshot.getChildren()) {

                String itemName="";
                if (ds.child("name").getValue(String.class)!=null) {
                    itemName= ds.child("name").getValue(String.class);
                }
                
                }
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });

Update: Here is a part of the Firebase Realtime Database:

  "Orders": {
    "table_1_order_7_date_29-04-22_time_18-17-49": {
      "comment_Text": "",
      "name": "Order_A",
      "orderDate": "18:17 (29.04.22)",
      "orderDateInMilliseconds": 1651249069304,
      "orderID": 2,
      "orderOtherInfo": "",
      "orderStatus": "ordered",
      "quantity": 1,
      "tableNumber": 1
    },
    "table_1_order_8_date_29-04-22_time_18-17-52": {
      "comment_Text": "",
      "name": "Order_B",
      "orderDate": "18:17 (29.04.22)",
      "orderDateInMilliseconds": 1651249072115,
      "orderID": 2,
      "orderOtherInfo": "",
      "orderStatus": "prepared",
      "quantity": 1,
      "tableNumber": 1
    },
    "table_1_order_9_date_29-04-22_time_18-17-54": {
      "comment_Text": "",
      "name": "Order_C",
      "orderDate": "18:17 (29.04.22)",
      "orderDateInMilliseconds": 1651249074747,
      "orderID": 9,
      "orderOtherInfo": "",
      "orderStatus": "prepared",
      "quantity": 1,
      "tableNumber": 1
    }
  },
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
VanessaF
  • 515
  • 11
  • 36
  • 3
    Please edit your question and add your database structure as a JSON file. You can simply get it by clicking the Export JSON in the overflow menu (⠇) in your [Firebase Console](https://console.firebase.google.com/u/0/project/_/database/data). – Alex Mamo Apr 23 '22 at 10:05
  • @AlexMamo: Thanks for your comment Alex. Unfortunately I am not allowed to share the database. But I analyzed the behaviour of the query and found out that the number of items returned by the query itself is random. I adjusted the question a little bit. Sometimes the query returns 0 matching items, sometimes 1 and sometimes all of them. The strange thing is this random behaviour. I execute the very same code all the time. Any idea why this is happening. I thought maybe it could have something to do with the Internet connection but the `onCancelled(DatabaseError databaseError)` is never called – VanessaF Apr 24 '22 at 08:12
  • @AlexMamo: Any comments to my last comment? I'll highly appreciate every further comment from you. – VanessaF Apr 27 '22 at 15:49
  • Show us then the structure using some dummy data. – Alex Mamo Apr 27 '22 at 19:38
  • @AlexMamo: Thanks for the comment. I added a part of the firebase database. When running the query for `òrderID=2`, sometimes 0 items are returned, sometimes 1 and sometimes 2. – VanessaF Apr 29 '22 at 16:29

1 Answers1

0

I cannot see any reasons why you get that randomness using the actual code. Maybe there is something else in your code, that we cannot see, that provides such a behavior. However, I'll try to provide the same solution but using get() and I highly recommend you try this in isolation, meaning without any other code in your activity class:

DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference ordersRef = db.child("Orders");
Query queryOrdesById = ordersRef.orderByChild("orderID").equalTo(2);
queryOrdesById.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            for (DataSnapshot orderSnapshot : task.getResult().getChildren()) {
                String name = orderSnapshot.child("name").getValue(String.class);
                Log.d("TAG", name);
            }
        } else {
            Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
        }
    }
});

The number of results returned should always be and the 2, if you have at least two orders, and the result in the logcat will be:

Order_A
Order_B
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hey VanessaF. Does it work now with the code in my answer? – Alex Mamo May 01 '22 at 07:20
  • Thanks Alex for your answer. Unfortantely your suggested query always returns nothing (I corrected the spelling mistake from my end `"orderID" instead of `oderID``). I also tried to insert the URL here `DatabaseReference db = FirebaseDatabase.getInstance().getReference();` such that I tried it with and without the URL. The result is always the same. The query does not return anything altough there are items in the firebase database that match the query – VanessaF May 01 '22 at 08:36
  • Oh, yes. It's `orderID` and not `oderID`. One more question, is your `Orders` node a direct child under the root? Besides that, what is the location of your database? – Alex Mamo May 01 '22 at 08:39
  • Thanks Alex for your comment and effort. I really appreciate it. `Orders` is in fact a direct child under the root and the location of my database is `europe-west1` – VanessaF May 01 '22 at 08:45
  • As for the randomness of my inital query, I would like to ask if there is a way to get to know the exact query that is being executed in the Firebase Database? Maybe this can be done in the Java code to get the exact query object that is being executed or maybe there is a log function in the Firebase Database to see what request it received. – VanessaF May 01 '22 at 09:07
  • If your database is located in another place than `us-central1`, then [it's mandatory to pass the database URL to the getInstance() method](https://stackoverflow.com/questions/67795058/getinstance-doesnt-work-with-other-location-than-us-central1-in-realtime-data). If the query succeeded then the `onComplete` is called with DataSnapshot object that contains all the data. There is no other way. Please add the location as my answer stats and tell me if it works. – Alex Mamo May 01 '22 at 09:16
  • Thanks for your comment. As described in my previous comment I tried your suggested code with and without the URL. In both cases your query returns nothing. The `onComplete` method is never called. I use the following line `DatabaseReference db = FirebaseDatabase.getInstance(FIREBASE_URL).getReference();` with the final variable `FIREBASE_URL` that contains the whole URL of the firebase database – VanessaF May 01 '22 at 13:07
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244375/discussion-between-vanessaf-and-alex-mamo). – VanessaF May 01 '22 at 14:25
  • Are you sure it's the correct URL? Besides that, if onComplete isn't triggered, most likely your device doesn't have an internet connection, right? – Alex Mamo May 02 '22 at 09:45
  • Thanks Alex for your comment. Yes, I am sure that it is the right URL as I use it as a constant also in other Fragments and there it works perfectly. And my device in fact has a Internet connection (I tested this). Still your code does not return anything. Besides that I have started a chat (see comment before) and there I share some interesting aspects that I have noticed regarding my problem with the randomness of my inital code. Would you mind having a look at it? I'll highly appreciate it. – VanessaF May 04 '22 at 16:19
  • If you try to change the field on which you are ordering the results, using something like `.orderByChild("name").equalTo("Order_A")`, are you getting the expected result? For example, `Order_A`? – Alex Mamo May 05 '22 at 05:28
  • Thanks Alex for your comment. I tried your suggested modification on your suggested code but the query still returns nothing. The `onComplete` method is never called – VanessaF May 06 '22 at 16:36
  • Then the single reason I can thing of, is that somehow, you don't have an internet connection on the device. – Alex Mamo May 07 '22 at 05:57
  • Thanks Alex for your comment. Actually I do have internet connection on the device. I checked that by also using another query (the "random query" from my initial code) together with your query. The "random query" still keeps returning a random number of matching itmes (altouth most often it does not return anything). But your query always returns nothing. I checked that about 1000 times on an Emulator and on a real device. Your query unfortunately does not return anything. – VanessaF May 07 '22 at 07:22
  • The strange thing is that I am using the Firebase Realtime database on this app on several other occasions, also with the same node `Orders`. There everything works perfectly. But the query mentioned in my post does not work properly. It keeps returning a random number of matching items. And your suggested get-query does not work at all. – VanessaF May 07 '22 at 07:25
  • I tested your suggested code now completely isolated in an empty Fragment that makes nothing other than executing the code in the `onCreate` method. Further, I tested your suggested approach with other nodes of the Firebase Database and other attributes. In all cases nothing is returned altough I can confirm that the device does have Internet connection. So I would assume that the get approach does not work in my app (I have never used it before). Maybe there are some version conflicts. So I'd like to focus more on my initial code that at least randomly returns something. – VanessaF May 07 '22 at 09:23
  • I'm not aware of any version conflict. So in my opinion, the get approach should also work. – Alex Mamo May 07 '22 at 09:25
  • Thanks for your comment and effort. I really appreciate it. Actually I have tested your suggested code now for at least 5 hours with all different combinations of nodes and attributes. I tested it both on an Emulator of Android Studio and on a real device. I tested it in combination with other Firebase Database calls and completely isolated (in an empty Fragment). I also made sure that it is the very first code that is executed such that there can't be any interference with other calls. Not once has it returned anything. The `onComplete` method has never been called. – VanessaF May 07 '22 at 09:34
  • I'm sorry to hear that, but I run out of solutions :| – Alex Mamo May 07 '22 at 09:37
  • That is really frustrating and I really don't know what to do. I would like to focus more on my initial approach that at least returns matching items altough the number of matching items is random. Can you think about some possible explanations for this? Is quite strange that a database returns random numbers for a query (this is the first time I have experienced this having used multiple database types during the last years). Is there a way to get to know the exact internal query of the Firebase Database to understand why it is returning a random number of items? – VanessaF May 07 '22 at 09:58
  • I think that you might consider writing directly to the Firebase team. – Alex Mamo May 08 '22 at 05:57
  • Thanks Alex for your comment. I am sceptical that the Firebase team will in fact try to help me on this issue as they are referring to Stackoverflow for coding issues on their website. So I will try to continue to understand why the Firebase Database returns a random number of matching items when executing the same (hardcoded) query on the very same database. At the moment my best guess still would be that there are some version conflicts or that some other Firebase calls that I use in the same app are interfering with this call and there are collisions. – VanessaF May 08 '22 at 15:42
  • I've never encountered anything like this. – Alex Mamo May 09 '22 at 09:07
  • Yes, I have also never encountered anything like this in none of the many different databases that I have used. It's extremely strange that the Firebase Database reacts like this. As I have already integrated Firebase on several occasions in my applications, I will try to figure this problem out at least for some time before removing firebase completely (and never ever using it again in case this problem remains because this is totally inacceptable). – VanessaF May 09 '22 at 17:04
  • Is there a way how I can read the logs on the Firebase db to see what kind of query it exactly gets? Or is there a way without using a query or the get method, to see what is in the database in the moment the query is submitted? The cause of the random number of returned items is either that the (hardcoded) query is somehow changed by my Java application, or that firebase db in fact internally returns a random number of items for the same query, or that the returned object from firebase is misunderstood by the firebase handling threads of my Java applications. I need to analyse those 3 steps. – VanessaF May 09 '22 at 17:11
  • I'm sorry but I'm not aware of something like that. – Alex Mamo May 09 '22 at 19:27
  • Is there a way to see or understand how the firebase handling threads in Java process an answer from the firebase database? I assume that there is something going wrong. The query itself is hardcoded in Java so I don't think that firebase missunderstands it as it returns matching items but unforunately the number of returned items is random. So I would more or less rule out the 1st possible cause for the problem. The second possible cause it that Firebase itself can't find all matching items with its internal search algorithms. I would not rule this out but I don't think it's very likely. – VanessaF May 10 '22 at 20:38
  • Is there a way to check the answers of Firebase for a given query without using Java or and other Programming language like you can do in some SQL Editors. Just the pure query? I would like to check whether the database itself also returns a random number of matching items without Android? But for me the most likely cause might be the Firebase handling threads in Android. Here I assume that there are some version conflicts or collissions with other Firebase calls. Maybe the threads fail to synchronize with each other and the returned items for one query are wrongly assigned to another Listener – VanessaF May 10 '22 at 20:46
  • I'm not aware of something like that. Try to create a new project in the console, as well as in Android Studio. – Alex Mamo May 11 '22 at 05:51
  • Thanks for your answer and quite frustrating to hear that Firebase does not provide any option of debugging the database or the Android code. What do you mean by "new project in the console"? And about the new project in Android Studio, shall I just copy and paste the existing project? Maybe one option that might help is to switch the server location of the Firebase Database. – VanessaF May 11 '22 at 16:42
  • Create a band new Firebase project, as well as in a new location. It would be interesting to know the reason for that randomness... – Alex Mamo May 11 '22 at 19:32
  • Thanks for your suggestion. I created a new Firebase project in a new location as you suggested. Unfortunately, the behaviour is the same :-(. I get a random number of matching items for the same query on the same database. – VanessaF May 22 '22 at 08:20
  • Add the project on GitHub and share the link here. I'll take a look at it. It will be useful to export the JSON from the Firebase Console. – Alex Mamo May 22 '22 at 08:24
  • Thanks for your answer and effort. I really appreciate it. It will take some time until I can share the project on GitHub as there is information in it that I am not allowed to share. I have to try to reduce the project as far as I can such that the behaviour is still visible. Maybe I will first try to ask another related question on StackOverflow because I have now spent many hours on this problem and I have found out that after a random number of executing the same query (from 1 to 100) within a very short timeframe (seconds) the database in fact returns all matching items. – VanessaF May 22 '22 at 08:34
  • Ok, looking forward to seeing your new question. – Alex Mamo May 22 '22 at 08:44
  • The strange thing is that sometimes the same code works well and immediately returns all matching itmes. I have now been dealing for 2 months with this issue and there were always some hours in which everything just works fine and Firebase returns all matching items for a query. But sometimes the same code (same project and same database) does not return all matching items immediately but just after executing the same query multiple times within a short timeframe. Earlier this day I had to execute the query 10 times within a second and suddently everything works well. – VanessaF May 22 '22 at 09:08
  • So are you getting now all results? No matter how many times you perform the query? – Alex Mamo May 22 '22 at 09:09
  • Yes at the moment it is fine, but I had experienced this behaviour before. Sometime everything worked just fine and I received all the results immediately. But most of the time it did not and I received a random number of matching items. So I anticipate that it (unfortunately) the behaviour will change again and it will not work fine any more. One thing I did find out is that if I get a random number of matching items, I'll have to execute the query multiple times repeatedly and from a certain time on the database returns all matching items and will continue to do so. This is quite strange – VanessaF May 22 '22 at 09:15
  • Just for the record: I have also tried your get approach and now at leat the `onComplete` method is called. However, I get the following error message "Index not defined, add ".indexOn": "orderID", for path "/Orders", to the rules". But actually I don't need the get method. I just use the normal query instead. – VanessaF May 22 '22 at 09:57
  • This [answer](https://stackoverflow.com/questions/53334616/firebase-query-doesnt-seems-to-work-in-andorid) should help, right? – Alex Mamo May 22 '22 at 10:22
  • Thanks for your answer. Is your linked answer something like defining the primary key? Because the attribute of the entries `orderID` itself is not really a primary key meaning that two entries can have the same `orderID`. This might also be the reason for the random number of returned items because when mutiple items had the same `orderID` the randomness could be observerd more often. – VanessaF May 22 '22 at 12:59
  • If a key is often changed and perform queries based on that key, that's most likely the reason why you're getting different ("random") results. – Alex Mamo May 23 '22 at 07:06
  • Hi Alex, it's me again unfortunately again having this problem with non-complete returns from the firebase database. Actually, one month ago I installed the app on my phone and in this app everything was okay and I always received the full results of the query. Now I reinstalled the app but I did not change anything about the firebase handling code and all of the sudden I have the same problem again, that firebase does not return the correct number of matching items. – VanessaF Jun 25 '22 at 09:49
  • Now when I execute the same query multiple times (5 times in a second) the probability is quite high that I get the full results. So I don't think that your suggestion from the last comment is still correct that "If a key is often changed and perform queries based on that key, that's most likely the reason why you're getting different ("random") results.", as I have not changed anything regarding the key and also nothgin regarding the firebase code. – VanessaF Jun 25 '22 at 09:49
  • I have noticed 2 things for the current problem (and I also noticed that earlier when having problems). 1) For some `oderID` the query immediately returns the correct number of matching items. But that's just the minority. For most `orderID` the query returns a fixed number of matching items but here the last n items (n can e.g. be 1, 2, 3 or 5) that have been inserted are not returned. – VanessaF Jun 26 '22 at 09:07
  • 2) When executing the same query (both my approach and your suggested get approach) multiple times on the same database within a short amount of time, the likelihood is quite high that the number of matching items is correct. Once the query has returned the correct number of items, it does not go back from here and keeps returning the correct numer of matching items for a specific `oderID`. So the fast execution of the query kind of updates the "view" the query has from the database because without the fast multiple execution the query misses the last n inserted matching items. – VanessaF Jun 26 '22 at 09:07
  • I'm sorry but I cannot figure that out. – Alex Mamo Jun 26 '22 at 19:46
  • Do you have any idea what the problem might be? There has to be a reason for this behaviour and it's not the Java code of the Query itself. What would be your best guests? I have spend so much time on that and I don't know what else to do. What would you advice me to do? – VanessaF Jun 27 '22 at 19:25
  • I'm sorry, but I haven't. I understand your frustration, but I recommend you again try to write the problem to the Firebase team. – Alex Mamo Jun 28 '22 at 06:12