1

addValueEventListener gives all the data whenever something changed in the database, due to this I have implemented addChildEventListener to get the only new item when there is a something new in the database.

Currently, the problem I am facing is whenever I open app, addChildEventListener fetch all the item one by one in onChildAdded method.

Is there any way that I can fetch only new items in Firebase Realtime Database? Here is my code:

                mDatabase.addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                    News news = dataSnapshot.getValue(News.class);
                    Log.i("YES-onChildAdded", news.getId()+"/"+news.getHeadline());
                }

                @Override
                public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                    News news = dataSnapshot.getValue(News.class);
                    Log.i("YES-onChildChanged", news.getId()+"/"+news.getHeadline());
                }

                @Override
                public void onChildRemoved(DataSnapshot dataSnapshot) {
                    News news = dataSnapshot.getValue(News.class);
                    Log.i("YES-onChildRemoved", news.getId()+"/"+news.getHeadline());
                }

                @Override
                public void onChildMoved(DataSnapshot dataSnapshot, String s) {
                    News news = dataSnapshot.getValue(News.class);
                    Log.i("YES-onChildMoved", news.getId()+"/"+news.getHeadline());
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Log.i("YES-Cancelled", databaseError.getMessage());
                }
            });
Faisal Shaikh
  • 3,900
  • 5
  • 40
  • 77
  • 1
    Any listener will immediately retrieve all data that it points to when you attach it, and subsequently any changes while the listener stays attached. There is no way to change this behavior. If you want "only new" data, you'll have to define what "new" means. E.g. if it's data after a certain timestamp, then include that timestamp in a query. Also see the linksin the comment I left just a while ago here: https://stackoverflow.com/questions/48049476/how-to-fetch-only-updated-object-from-relatime-firebase-database#comment83074375_48049476 – Frank van Puffelen Jan 01 '18 at 19:23

1 Answers1

4

When you attach a listener on a particular DatabaseReference it means that the listener will retrieve all data from that location where the reference points to. Because Firebase database doesn't store metadata you need to add a TIMESTAMP for each record yourself. Defining a certain data then you can create a query to filter your database accordingly. Unfortunately, this is a behaviour that cannot be changed in Fireabse.

Assuming you have a node named item and each item within this node has a TIMESTAMP correctly set, the code to query a database using a TIMESTAMP should look like this:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("item").orderByChild("timestamp");

Further more you can query your database using limitations like this:

Query query = rootRef.child("item")
     .orderByChild("timestamp")
     .startAt(startingTime)
     .endAt(endingTime);
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Can you tell how the query will be as I can't see any method with I can filter data using a timestamp? – Faisal Shaikh Jan 04 '18 at 14:54
  • Your answer fixed my issue but currently, it also fetches the item with time "startingTime" but this is already in local database, can we fetch the result after "startingTime"? – Faisal Shaikh Jan 04 '18 at 17:23
  • you saved my several hours 2 times in single SO question. Big Thumb Up for you. – Faisal Shaikh Jan 04 '18 at 17:32
  • your answered solved my issue but created a new issue. Now `onChildChanged` don't revoke when old items are modified. Is there anything we can do? – Faisal Shaikh Jan 09 '18 at 10:47
  • @FaisalShaikh This is basically another question. In order to follow the rules of this comunity, please post another fresh question, so me and other users can help you and don't forget to add an [mcv](https://stackoverflow.com/help/mcve). – Alex Mamo Jan 09 '18 at 10:51
  • Sure. I will do. – Faisal Shaikh Jan 09 '18 at 10:54
  • @FaisalShaikh I assume for onChildChanged, you just have to update the timestamp value for the child? so it get's picked up? then you'd have to figure out how to avoid duplicates – Jessicardo Dec 31 '19 at 04:55