br00
br00

Reputation: 1454

Firebase ChildEventListener if no data has been retrieved

I'm using Firebase in my app. I have a list of element to retrieve using this code:

FirebaseDatabase.getInstance()
.getReferenceFromUrl("myUrl")
.orderByChild("timestamp")
.addChildEventListener(this);

What's the best Approach to know if a ref url has no data inside? Because using ChildEventListener is not possible.

ChildEventListener has only these 4 methods: onChildAdded(), onChildChanged(), onChildRemoved(), onChildMoved().

None of these method is called in case of your object has no item inside.

So my question is. Do I have to use a ValueEventListener as well? I guess onDataChange() is called if no item has been found.

A possible scenario: You have a list of item to retrieve and populate using ChildEventListener. You want to cover the case when no item has been retrieved. So show a text "No data" instead of the list.

Upvotes: 3

Views: 1499

Answers (4)

Delark
Delark

Reputation: 1323

For those looking for a reactive solution to this, the only available seems to be to stablish a direct communication between a databaseReference cache && your cached List (the one handling your childEventListener changes).

Think about it... When the databaseReference stays unchanged, then the cached List stays as usual, handling changes from the childEventListener accordingly.

Once a situation in which a reference change arises, there is absolute no reason for us to keep caching, as the old cache belongs to a different reference anyways.

The secret here will be this: a cache.clear() should happen IF & ONLY IF the reference is INDEED DIFERENT from that of the previous one.

!newDatabaseRef.getPath().toString().equal(oldPath)

if tests true then:

 oldPath = newDatabaseRef.getPath().toString();

and then:

cache.clear();

Once a chache.clear() has been performed, a manual consumption must be executed in order to emulate a DB callback.

listener.accept(cache); //please de-reference

and this consumption must be done BEFORE a potential TRUE callback from the DB arrives (in case the reference is not empty).

Just be careful with race conditions.

Upvotes: 0

Abhishek
Abhishek

Reputation: 1261

You can always use just a valueEventListener and onDataChange just check if datasnapshot.exists(). In line with the javadoc here -> https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#exists

so in your case

    FirebaseDatabase.getInstance()
        .getReferenceFromUrl("myUrl")
        .orderByChild("timestamp")
    .addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()){
        //Show text retrieved


         } else {
    //Show "No data"
    }
        }
@Override
public void onCancelled(DatabaseError databaseError) {
 Log.v(FB_ERROR_TAG, "Error in Database Connection");
}
 });

Upvotes: 1

koceeng
koceeng

Reputation: 2165

As far as I know, if you request data by addChildEventListener and addValueEventListener on the same data path directly after each other (in the code), you will have result of addChildEventListener completed first, then onDataChange inside ValueEventListener will be executed.

So my solution is doing like this:

Boolean childExist = false;

ref.addChildEventListener(new ChildEventListener() {
    ... onChildAdded() {
        // you can use List or Map here, this Boolean just to indicate if child exist or not
        childExist = true;
    }
    ...
})
ref.addValueEventListener(new ValueEventListener() {
    ... onDataChange() {
        // code you place here will be executed AFTER all of the event inside ChildEventListener is done
        // here the value of childExist will really indicate if there is child or no
    }
    ...
});

Upvotes: 3

user3476154
user3476154

Reputation:

If all you want is to show "No data" when there are no results you can just set the text value of your label to "No data" by default and have the firebase query overwrite it. If there are no results it simply won't get overwritten.

Upvotes: 0

Related Questions