Reputation: 11
I would like to allow my users to search other users and add them as friends. I have around 6,000 user nodes in my Firebase database, so obviously searching it is quite a heavy operation. I created a separate node from my "users" node, called "friendsIndex" at the root directory, and populated it with the minimum information needed for the search:
friendsIndex: {
$userID: {
name: "firstName",
lastName: "lastName",
profileImg: "urltoImage..."
},
....
}
My database rules have this:
"friendsIndex":{
"$userID":{
".indexOn": ["name", "lastName"]
}
},
The user search function looks like:
Query mQuery = Database.child("friendsIndex").orderByChild("name").startAt(searchWord).endAt(searchWord+"\uf8ff");
mQuery.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user;
for (DataSnapshot eventSnapshot : dataSnapshot.getChildren()) {
user = eventSnapshot.getValue(User.class);
//more code..
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
But I'm still getting this error:
08-31 13:03:28.354 3916-3925/com.learnArabic.anaAref E/System: java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
08-31 13:03:28.364 3916-17998/com.learnArabic.anaAref E/RunLoop: 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: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
08-31 13:03:28.379 3916-3916/com.learnArabic.anaAref E/UncaughtException: java.lang.RuntimeException: 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
at com.google.android.gms.internal.mz.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6247)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
Caused by: java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available
Can't think of any less heavy way to perform this search, any ideas?
Upvotes: 0
Views: 767
Reputation: 860
The exception is giving a hint but a wrong url. The correct url for filtering is https://firebase.google.com/docs/database/android/lists-of-data#filtering_data. From this page the method limitToFirst()
can be used to limit the number of results from starting of the list. I think this answers your question :
Can't think of any less heavy way to perform this search, any ideas?
You can use other methods to handle the situation when users are deleted between two queries. For example you can orderByKey()
and for second query onward use startAt(lastKey)
.
Upvotes: 2