1

First of all, I know it's common question, but I am really distracted right now, can't really get what I have to do, change schema (which will take too long) or I have some mistake in my code, here is a schema of Firebase nodes, example : enter image description here

here is how I try to query that data :

firebaseDatabase = FirebaseDatabase.getInstance().getReference()
                        .child("Statistic");

        final Query query = firebaseDatabase
                .orderByChild("Programa")
                .equalTo("0010104")
                .limitToFirst(10);


        query.addValueEventListener(new ValueEventListener()
        {
            public void onDataChange(DataSnapshot dataSnapshot)
            {
               for(DataSnapshot s : dataSnapshot.getChildren())
               {
                   Statistic statistic = s.getValue(Statistic.class);
                   Log.d("Found : ",statistic.getFakulteti());
               }
            }

            public void onCancelled(DatabaseError databaseError)
            {
                DialogFactory.errorPrompt(activity).show();
            }
        });

but querying doesn't works, after waiting for like minute or half, it tries to get all the data from Firebase that of course causes outOfmemory exception.

Error Log :

Firebase Database encountered an OutOfMemoryError. You may need to reduce the amount of data you are syncing to the client (e.g. by using queries or syncing a deeper path). See https://firebase.google.com/docs/database/ios/structure-data#best_practices_for_data_structure and https://firebase.google.com/docs/database/android/retrieve-data#filtering_data
                                                                        java.lang.OutOfMemoryError: Failed to allocate a 27113000 byte allocation with 16777216 free bytes and 24MB until OOM
                                                                            at java.lang.StringBuilder.toString(StringBuilder.java:408)
                                                                            at com.google.android.gms.internal.zzaje.toString(Unknown Source)
                                                                            at com.google.android.gms.internal.zzajc.zzsm(Unknown Source)
                                                                            at com.google.android.gms.internal.zzajc.zzso(Unknown Source)
                                                                            at com.google.android.gms.internal.zzajc.zza(Unknown Source)
                                                                            at com.google.android.gms.internal.zzajc$zzc$2.run(Unknown Source)
                                                                            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
                                                                            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                            at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
                                                                            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                                            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)

rule i tried :

{
  "rules": {
    ".read": true,
    ".write": false,
      ".indexOn" : ["Programa"]
  }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

2 Answers2

1

If your database contains a very large number of Statistic entries, you should add an index for Programa. Indexing is described here. The presence of an index allows much of the query filtering to occur on the server side and reduces the amount of data transferred to the client.

Your logcat output probably contains a warning like this:

W/PersistentConnection: pc_0 - Using an unspecified index. Consider adding '".indexOn": "Programa"' at Statistic to your security and Firebase Database rules for better performance

The rule for the index must include the path to your data. If Statistic is the root of the path, the rule would be:

{
  "rules": {
    ".read": true,
    ".write": false,
    "Statistic":{
      ".indexOn":"Programa"
    }
  }
}

When the rule is correctly specified, you will not see the warning in logcat about Using an unspecified index. If you continue to see the warning, the rule is not correct.

Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
  • I will try it in few minutes and will reply asap , thank you in advance –  Dec 01 '16 at 17:40
  • i tried indexing , probably it's for rest api only , error i am getting right now ( i deleted indexing, because it was not reading data at all , not even sending request after that) –  Dec 02 '16 at 12:08
  • Indexing works for all APIs, including Android. Post the rules you tried. – Bob Snyder Dec 02 '16 at 14:12
  • { "rules": { ".read": true, ".write": false, ".indexOn" : ["Programa"] } } –  Dec 02 '16 at 14:35
0

In your question I can see multiple things... The first one is, your programa key is an String, then if no exists a string value equal to "0010104", don't find anything and if we supose that exists then you get the ten first ones. Is possible this case? If you want to get string key to contains in a part "0010104" then you need yo use startAt() or endAt() instead of equalsTo().

The second one is, how many nodes would contains Statistic node? If your answer is hundred or less (for example), then we can't do anything but if your answer is infinite then is the typical case of firebase, normalize the firebase database, how to do this? Read this post that I answered yesterday about this theme.

Let me know if I have helped you and good programming!

Community
  • 1
  • 1
  • there is 28k objects of Statistic, i tried also the start and endAt and doesn't works, also indexing which than i find out only works on rest api , should i move on rest api? normalize firebase database , yeap as i mentioned it will take too long too too long :D to refactor that data right? unless there is anyway for quick refactoring which i don't know –  Dec 02 '16 at 12:18