0

On an Android application which must works offline most of the time I need, when it's online, to do some synchronous operations but Firebase always take the value from the cache when I need the value in the servor , Here a exemple

Query query = FirebaseDatabase.getInstance().getReference()
        .child("Post")
        .child(UserChannel)
        .child("Post");
query.keepSynced(false);

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if(dataSnapshot.exists()){
            Log.d(TAG, "Posts founded" );

            for(DataSnapshot snapshot: dataSnapshot.getChildren()){
                Posts thepost= snapshot.getValue(Posts.class);

                Log.d(TAG, "Post found");  

                ListPosts.add(thepost);
            }
        }else {
            Log.d(TAG, "  no post could be found.");              
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});

Here I use addListenerForSingleValueEvent for load posts from a specific user , it works fine but if the user add a new post in the child and I try to reload all his posts , the new post wont be loaded . I assume Firebase load the post from the cache how can I bypass this the cache to load only from servor ?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • `addListenerForSingleValueEvent` will return the latest value from the cache, and then refresh that cache with data from the server. If you call `keepSynced` in time, it will ensure the cache is up to date, but you might have a race condition here - in that the cache hasn't been updated yet when you call `addListenerForSingleValueEvent`. The solution is always the same: don't mix `addListenerForSingleValueEvent` with disk peristence, but use `addValueEventListener` and be prepared for multiple calls to `onDataChange`. See https://stackoverflow.com/a/34487195 – Frank van Puffelen Aug 25 '20 at 19:59
  • I used your advice and founded the answer thanks you ! –  Sep 18 '20 at 21:04

1 Answers1

3

If you want your app to get data when a new child it's added use the following

        databaseReference.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {
            
        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot snapshot) {

        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

Inside the onChildAdded add what you want to happen when a child it's added. Be aware that onChildAdded gets the initial data and then will trigger again for last child added. For additional information check this

Laurentiu Daniel
  • 381
  • 2
  • 10