get child nodes having large data from firebase realtime database - android

I want to get child of node using addValueEventListener(). when books data is few, it works properly but when books count is more than 30000 it gives error as "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)."
Firebase data structre is as
booksData
123 (book id)
bookname : ""
writer : ""
price : ""
category : ""
publicher : ""
...
456 (book id)
bookname : ""
writer : ""
price : ""
category : ""
publicher : ""
...
.... and so on. having vast data
(Data structure & name is changed just for sample)
I tried in android as
userIDRef1.child("booksData").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Log.e(TAG, "in get booksData");
ArrayList<BooksWrapper> booksList = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
BooksWrapper vtw = postSnapshot.getValue(BooksWrapper.class);
booksList.add(vtw);
}
userIDRef1.child("booksData").removeEventListener(this);
Log.e(TAG, "daybooks data size is : "+booksList.size());
if (booksList.size() >0){
db.addBookData(booksList);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
// Failed to read value
Log.e(TAG, "Failed to read app title value.", error.toException());
}
});
is there any way to get data in chunks as first 1000 books then next 1000 & so on...? Any solution please...

Related

Firebase realtime database list of values retrieved

Dear Friends,
I am accessing data from a Firebase database, however I am unable to get a list of my data.
I am getting the following exception:
E/UncaughtException: com.google.firebase.database.DatabaseException: Can't convert object of type java.util.ArrayList to type com.sg.rapid.Models.AlaramData`
here is my code:
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
AlaramData usersList = dataSnapshot.getValue(AlaramData.class);
String name = usersList.getStatus();
childList.add(usersList);
// here you can access to name property like university.name
}
Log.d("", "Value is: " + childList);
//Create a List of Section DataModel implements Section
sections.add(new SectionHeader(childList, "2018", 1));
adapterRecycler.notifyDataSetChanged();
}
Thanks in advance.
Reading the error message, we can understand that the method is returning an ArrayList of your elements, then I noticed you used the wrong variable there.
It should be using postSnapshot instead of dataSnapshot. Try this:
AlaramData usersList = postSnapshot.getValue(AlaramData.class);
I have solved the issue by changing the json structure in firebase database.
the code as follows:
// Read from the database
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
Log.d("", "onChildChanged:" + dataSnapshot.getKey());
sections.clear();
childList.clear();
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
AlaramData alaramData = postSnapshot.getValue(AlaramData.class);
int x = 0;
// here you can access to name property like university.name
childList.add(alaramData);
}
Log.d("", "Value is: " + childList);
//Create a List of Section DataModel implements Section
sections.add(new SectionHeader(childList, "2018", 1));
adapterRecycler.notifyDataChanged(sections);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("", "Failed to read value.", error.toException());
}
});

Firebase sorting data based on child not working

I'm trying to develop a simple application to learn firebase database.
Here is my realtime database schema
mydirectory
-contact_list
-LOyDhepB_IZlM6lZtko
mobileNumber: "9385746982"
name: "Jay"
-LOyDhetiPHalLhXrOaU
mobileNumber: "8000478912"
name: "Ravi"
-LOyDhetiPHalLhXrOaV
mobileNumber: "123456789"
name: "ABC"
-LOyDheubruATyyBp8dG
mobileNumber: "023456879"
name: "XYZ"
I want to get the list of data ordered by name
So I'm using this snippet to load the data in my android application
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("contact_list").orderByChild("name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> objectMap = (HashMap<String, Object>) dataSnapshot.getValue();
Master.personList.clear();
for (Object obj : objectMap.values()) {
if (obj instanceof Map) {
Map<String, Object> mapObj = (Map<String, Object>) obj;
String name = (String) mapObj.get("name");
String mobileNumber = (String) mapObj.get("mobileNumber");
Person person = new Person(name, mobileNumber);
Master.personList.add(person);
populateListView();
}
}
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w("ANDs", "Failed to read value.", error.toException());
}
});
But it does not sort data based on the alphabetical order of name
key. Am I doing anything wrong or missing something?
P.S.
I've also indexing rules (ref), but still result is same! It doesn't sort data alphabetical wise.
{
"rules": {
"mydirectory": {
"contact_list": {
"$user_id": {
".indexOn": ["name"]
}
}
},
".read": true,
".write": true
}
}
I've tried many things from other posts like this topic but nothing works! Please don't make it duplicate instead please help me to solve it!
A HashMap can only contain a key and a value. And the keys in a Map are by definition not ordered. So when you call dataSnapshot.getValue(), you're throwing away all ordering information.
To maintain the order, you'll need to loop over dataSnapshot.getChildren():
public void onDataChange(DataSnapshot dataSnapshot) {
Master.personList.clear();
for (DataSnapshot contactSnapshot: dataSnapshot.getChildren()) {
String name = contactSnapshot.child("name").getValue(String.class);
String mobileNumber = contactSnapshot.child("mobileNumber").getValue(String.class);
Person person = new Person(name, mobileNumber);
Master.personList.add(person);
}
populateListView();
}
You'll also notice that I use child(...) to get a child snapshot for a specific property and get the String value from it. Your approach for that would work too, but I find that I get better error messages when I stick to a snapshot longer (instead of converting to a Map).

Reading data from firebase database fails

I am reading the data from the firebase database.Following is snapshot of the data stored in database.
In the snap string starting with "8SS..." is the uid of the user. Following is the code for retrieving the data from firebase database.
//To check if uid of current user and database user matches.
Query q = FirebaseDatabase.getInstance().getReference().child("Location").child(user.getUid()).equalTo(FirebaseAuth.getInstance().getCurrentUser().getUid());
q.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
Log.d(TAG, "Yay!!");
User us = singleSnapshot.getValue(User.class);
String string = "Name: "+ us.getName()+"\nAddress: "+ us.getlat()+ us.getlon()+ "\n\n";
n.setText(string);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// read query is cancelled.
Log.d(TAG, "loadPost:onCancelled", databaseError.toException());
}
});
User class contains getters and setters.
The error is that only empty Text View appears concluding reading from database fails.
How to evaluate if query is true or false?
What is the error while reading from ValueEventListener()?
I tried using this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Location").child("8SS0uk4FmiPUtXP208Tx8Cqxt2z2");
And then calling on ref.addListenerForSingleValueEvent() but still nothing gets displayed.
I tried using this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Location").child(user.getUid());
This gives dataSnapShot : "DataSnapshot={key='-Kn...', value="latitude:.., longitude:..., Name:..."}. But this is not how I expected it to be.
The database structure should have been Location --> Uid --> Name : "Jane", .. .
This is my code for inserting data in the database.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser() ;
refDatabase = FirebaseDatabase.getInstance().getReference().child("Location").child(user.getUid());
DatabaseReference newPost = refDatabase.push();
//the push() command is already creating unique key
Map<String, String> mapname = new HashMap<String, String>();
mapname.put("Name", n.getText().toString());
mapname.put("latitude", Double.toString(lat));
mapname.put("longitude", Double.toString(longt));
mapname.put("user id", user.getUid());
newPost.setValue(mapname);
I solved this question by introducing multiple for loops.
So, the snapshot of my first child was dataSnapShot : "DataSnapshot={key='-Kn...', value="latitude:.., longitude:..., Name:..."}.
Below is the code to extract all the values and keys :
mRef.addValueEventListener(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "Children" + dataSnapshot.getKey());
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
String st = singleSnapshot.getKey();
Log.d(TAG, "Yay!!" + singleSnapshot.child(st));
st = "";
int count=0;
for(DataSnapshot singleSnap : singleSnapshot.getChildren()) {
Log.d(TAG, "String" + singleSnap.getValue());
//n.setText(us.getName());
if(count==0) {
st = "Name: " + singleSnap.getValue() + '\n';
}
else if(count==1) {
st = st + "Latitude: " + singleSnap.getValue() + '\n';
}
else if(count==2) {
st = st + "Longitude: " + singleSnap.getValue() + '\n';
}
count++;
}
final TextView rowTextView = new TextView(Menu5.this.getActivity());
rowTextView.setText((CharSequence) st);
ll.addView(rowTextView);
}
}
This gives single key and value pair for every unique id of created by push.So, I had to hard code the concatenation and display as the structure will remain same throughout the app.
Why are you using equal to and then getting the current user. .child(user.getUid()) should already be your current user which gives you the value of the child you are trying to listen to.
I think the uuid's are the children of "8SSOuk.......".
So it should look something like this:
FirebaseDatabase.getInstance().getReference().child("Location").child("8SSOuk.......").child(user.getUid());

Add Firebase List of Object from DataSnapshot to Array

I have stored my Images URLs on Firebase Database, as I have been reading here it was the way to go.
Now I need to retrieve the 5 Picture Objects form the List and put them into an array for later use.
So I add a SingleValueEvent to my Reference which is on UserId Node and get a DataSnapshot Object, which I check for null.
The problem is that even if I only have a list of 5 Pictures in my Database, when iterating on the DataSnapshot Object it adds 19 Picture Objects into the Array...
02-14 15:13:45.375 21952-21952/com.example I/EditProfileFragment:Picture Array : 19
What am I missing here?
The Json looks like this:
PicturesUrls {
UserID {
randomID{
pictureName : "Main Picture"
pictureUrl : "URL"
}
randomId
pictureName : "Second Picture"
pictureUrl : "URL"
randomId {
pictureName : "Third Picture"
pictureUrl : "URL"
}
}
}
Here is my Code:
ArrayList<Object> mPicturesArray = new ArrayList<>();
....
....
mPicturesUrlRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null) {
addPicturesToArray(dataSnapshot);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
private void addPicturesToArray(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
Picture picture = child.getValue(Picture.class);
mPicturesArray.add(picture);
Log.i(LOG_TAG, "One Picture added : " + picture.getPictureName());
}
Log.i(LOG_TAG, "Picture Array : " + mPicturesArray.size());
}
Hummm....
Ok so I have changed the ArrayList to a HashMap and things are working as expected now.
No idea why but...

How to retrieve data from a Push firebase data

i used push to save data on firebase and it automatically saves with its own push id, now am trying to retrieve the data to use for history but i cant because of that id. this is what i have
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child(Config.MESSAGE).child(userName).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Getting the data from snapshot
Message message = dataSnapshot.getValue(Message.class);
for (int i = 0; i < 11; i++) {
message.setMessage(message.getMessage() + i);
message.setTitle(message.getTitle() + i);
message.setTime(message.getTime() + i);
System.out.println("we in" + message.getTitle());
/******** Take Model Object in ArrayList **********/
CustomListViewValuesArr.add(message);
Resources res =getResources();
/**************** Create Custom Adapter *********/
adapter=new CustomAdapter(CustomListView, CustomListViewValuesArr,res);
list.setAdapter(adapter);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Log.w(TAG, "getUser:onCancelled", databaseError.toException());
// ...
}
});
}
and this is what the data looks like
-KRjrOKWwCa6zmhyyhvf
body: "Hi how you doing"
time: "test"
title: "push"
-KRjjiiuwCa6zmhKVsro
body: "Hi how you doing"
time: "test"
title: "push"
-KRjrOef45a6zmhKbytr
body: "Hi how you doing"
time: "test"
title: "push"
i keep getting null everytime
It looks like you have a list of messages for a user. But your code seems to treat the result as a single message. That will not work.
If this is indeed what's going on, try:
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
Message message = messageSnapshot.getValue(Message.class);
We recently added a sample about this to the Firebase documentation on querying data.

Categories

Resources