RecyclerView swipe to add older Firebase Data - android

I am facing a problem with adding older data to RecyclerView with SwipeRefreshLayout so, here is how i retrieve from Firebase and put data into RecyclerView
private void messageList() {
referenceMessages.orderByKey().limitToLast(10).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
MessagesInfo messages = dataSnapshot.getValue(MessagesInfo.class);
result.add(messages);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
MessagesInfo messages = dataSnapshot.getValue(MessagesInfo.class);
result.remove(messages);
adapter.notifyDataSetChanged();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
as you can i see, I set limit of retrieved messages to last 10, what means the 10 newest messages will be displayed. So far everything works great, the messages are displayed like that
-20thmessage(the oldest)-
-21stmessage-
-...-
-29thmessage-
-30thmessage(the newest)-
now i use SwipeRefreshLayout like that
private void swipe(){
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
referenceMessages.orderByKey().endAt("-LHUhkub4iaZNNzmtUcs").limitToLast(10).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
MessagesInfo messages = dataSnapshot.getValue(MessagesInfo.class);
recyclerView.scrollToPosition(0);
result.add(0, messages);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
and it retrieves data properly, i mean previous 10 messages before hardcoded endAt() but after swiping places data not properly. If i dont use index 0
new data is placed at the botoom of latest message and it looks like that
-30thmessage(the newest)-
-10thmessage-
-...-
-19thmessage-
-20thmessage(the newest)-
and when i use index 0 data is added from the top of already loaded messages but like that
-20thmessage(the oldest)-
-19thmessage-
-...-
-11ththmessage-
-10th-
so it is added upside-down. Hope you understand me :) any inputs are highly appreciated

You might try clearing the list first and then add the new messages.
Android SwipeRefreshLayoutBasic

Related

How can i execute android firebase multiple childeventlistiner in sequence order

I have 4 ChildEventListener in one activity. When activity launches 4th ChildEventListener executes 1st then 3rd, 2nd, 1st and some time it will be in reverse order 1,2,3,4. so it is not loading sequentially. ChildEventListener listeners example are mentioned below.
AfirebaseDatabaRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
BfirebaseDatabaRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I don't think you understand these listeners well, callback is being called for the node that is registered to it only this node no one else, so if you have multiple nodes and every node has callback registered to it, when change happens to any node the corresponding callback ONLY will be triggered, so the sequence should be changes in the nodes not the callbacks, i hope this answers your question.

Get the whole values from one key in firebase [duplicate]

This question already has an answer here:
ArrayList not updating inside onChildAdded function
(1 answer)
Closed 4 years ago.
I want to get the whole value(0~5) from destinations
This is part of json data in realtime database
{"results" : [{
"destin_num" : 6,
"destinations" : [ "asdf", "qwwee", "zzzxcv11", "jkkk", "lkjhhg", "zxcvb" ],
"name" : "asdfasdfff",
"order" : 2,
"required_time" : "6hours" }]}
the value I want to put in the String List , I use ChildEventListener() to add the value into List, but the value can't put into the List after finish the ChildEventListener().There will be nothing in List direction How to get the values?
List<String> direction=new ArrayList<String>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
DatabaseReference reference_contacts = FirebaseDatabase.getInstance().getReference("results").child("1").child("destinations");
reference_contacts.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String data=dataSnapshot.getValue().toString();
direction.add(data);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
for(int i=0;i<direction.size();i++){
Log.e("Get data",direction.get(i));
}
}
It's because data is loaded from Firebase asynchronously. Your for loop printing the values is actually run before onChildAdded ever gets called. It's easiest to see this by adding some logging:
Log.i("Firebase", "Before adding listener");
reference_contacts.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.i("Firebase", "In onChildAdded");
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) { }
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) { }
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) { }
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Log.i("Firebase", "After adding listener");
When you run this code it prints:
Before adding listener
After adding listener
In onChildAdded
That is probably not the order you expected. But is completely explains why the direction list is empty when you print it, the data hasn't been loaded yet, so onChildAdded has never been invoked.
The solution is typically to add the code that requires the data into the onChildAdded method:
So:
reference_contacts.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String data=dataSnapshot.getValue().toString();
direction.add(data);
Log.i("Got data",direction);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
If you only want to show the data once everything is loaded, you can use a ValueEventListener instead:
reference_contacts.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot: snapshot.getChildren()) {
String data=dataSnapshot.getValue(String.class);
direction.add(data);
}
for(int i=0;i<direction.size();i++){
Log.e("Get data",direction.get(i));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Note that this is an incredibly common source of confusion for developers new to Firebase (and asynchronous APIs in general). I highly recommend studying some of the answers to some of these previous questions about the topic:
Setting Singleton property value in Firebase Listener
getContactsFromFirebase() method return an empty list (which also shows how to define a custom interface to allow the code that requires the data to be outside onChildAdded/onDataChange.
can't get values out of ondatachange method
ArrayList not updating inside onChildAdded function

ArrayList loses elements after onChildAdded (Android Studio & Firebase)

public void readUniversity(){
ChildEventListener uniListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//Log.d(LOG_TAG, dataSnapshot.getKey());
University uni = dataSnapshot.getValue(University.class);
universitieslist.add(uni); //Adding to an ArrayList of type University
//Log.d(LOG_TAG, universitieslist.size()+"is the size");
arrayofUniversities.add(uni.getName()); //Adding name of University to list
//Log.d(LOG_TAG, adapter.getCount() + " items");
//Log.d(LOG_TAG, arrayofUniversities.size()+" is the size");
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
DatabaseReference uniReference = database.getReference("note-retrieve/Universities");
uniReference.addChildEventListener(uniListener);
}
The code is pretty much self explanatory. I am using arrayofUniversities a list to populate a spinner so I need an adapter. I am populating the spinner with the names of the Universities
I am storing the University Objects in universitieslist
The problem I have is when I leave the readUniversity() method I lose every element in universitieslist and arrayofUniversities even though my spinner is populated with these.
Its very strange as the list should have the objects stored.
Also, I have my adapter at the very top of the code in onCreate().
Try this way. Hope it will work .. :)
private Arrylist<University > universityList = new ArryList<>();
private Arrylist<String> universitysName = new ArryList<>();
mDatabase.getReference().child("path")
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null) {
University mUniversity = dataSnapshot.getValue(University
.class);
universityList.add(mUniversity);
universitysName.add(mUniversity.getName);
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The problem seems to be with the adapter, if you can see the logs but the adapter is not updating, then is because the adapter is not being notified the data set has changed
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null) {
University mUniversity = dataSnapshot.getValue(University
.class);
universityList.add(mUniversity);
universitysName.add(mUniversity.getName);
//UPDATE YOUR ADAPTER HERE
//spinnerAdapter.notifyDataSetChanged();
}
}
But I think the real problem is the origin of your current problem: You are getting each child. This is a way to do it, but for this case where you need all the data first and when that is ready show the spinner with the elements to the user, you should better get all the list elements in one query.
database.getReference("note-retrieve/Universities")..addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
University mUniversity = dataSnapshot.getValue(University
.class);
universityList.add(mUniversity);
universitysName.add(mUniversity.getName);
//ONCE THIS IS DONE, THEN PASS THE ARRAY TO THE ADAPTER
}
//The loop here is over, so you can set the adapter with the full list of data/universities
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

How to get childs of firebase database to an android listview

I have been searching for this but have not managed to find what I was looking for.
Here is an image of what I have in firebase.
I need to show it in the listview but also I need to show it dynamically. Such as if there are 30 links it should show 30 items in the listview and if there are 50 links here in Firebase the listview should have 50 items.
What would be the best possible way to do this?
Thanks
I have found a solution.
listview=(ListView)findViewById(R.id.listview);
final ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,list);
listview.setAdapter(adapter);
dref=FirebaseDatabase.getInstance().getReference();
dref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
list.add(dataSnapshot.getValue(String.class));
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
list.remove(dataSnapshot.getValue(String.class));
adapter.notifyDataSetChanged();
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
This will show all the data of child in a listview

Retrieve Random Object from Firebase Android

I want to be able to return random objects from the following image:
And not just the first object (-Kci1vM1dVBYBcPW7QA) which returns as is already. I have inserted the code from my app where it is currently reading from. The variables one, two and three are currently reading the first object but I want them to be able to retrieve random objects.
public void displayDeals(){
databaseReference.child("FruitDeals").child("bR4sR4flMkYFrw1SzuWA8hpOnY52").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
deals_information = dataSnapshot.getValue(Deals_Information.class);
one = deals_information.getDeal();
two = deals_information.getPrice();
three = deals_information.getAisleNum();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
}

Categories

Resources