m.yuki
m.yuki

Reputation: 855

Firebase onChildChanged returns null DataSnapshot

I have this firebase database

enter image description here

and I have assigned listner to the field driverId to check if it's been changed by this code

myReq = FirebaseDatabase.getInstance().getReference().child("requests").child(userId);
myReq.addChildEventListener(this);

then I implemented onChildChanged like this

 @Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {


    String driverID = dataSnapshot.child("driverId").getValue(String.class);

    Toast.makeText(PlacesDemo.this, "GREAT " + driverID, Toast.LENGTH_SHORT).show();

}

then when i change the driverId it's been trigged but passing a null DataSnapshot the Toastappears ( GREATE NULL)

Am I using a wrong listener or there's something else ?

Upvotes: 0

Views: 4068

Answers (3)

DoruChidean
DoruChidean

Reputation: 8138

There is another case when one could get a null response, even though the remote database has children.

If you have database.setPersistenceEnabled(true);, you might have a case where locally there are no children, but on remote will be, until next sync.

Use database.getReference("your_node").keepSynced(true); to always get the latest data on remote.

Upvotes: 2

Lewis McGeary
Lewis McGeary

Reputation: 7932

When onChildChanged is called, the dataSnapshot is the child that changed, not the parent node that you set the listener on.

So when you change the driverId in this case, the dataSnapshot is just giving you the new driverId and value. The driverId entry doesn't itself have another child called also called "driverId", hence the NULLwhen you ask for that. You need to ask directly for the value of the dataSnapshot:

String driverID = dataSnapshot.getValue(String.class);

An alternative resolution would be to add the listener to the "requests" node itself instead of listening only to this specific 'request'; the dataSnapshot(ie. child) would then be all of the request data (the VRFq.. key and all of its children). You could then use dataSnapshot.child("driverId")... etc to get the data from the snapshot.

Upvotes: 1

Bob Snyder
Bob Snyder

Reputation: 38319

In the code you posted, mReq is a reference to the $userId child of requests. That node has children: driverId, to, from, userId.

When you add a child listener to mReq, the callbacks fire for each of the four children. You could filter for changes to driverId using this code:

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
    if (dataSnapshot.getKey().equals("driverId")) {
        String driverID = dataSnapshot.getValue(String.class);
        Toast.makeText(PlacesDemo.this, "GREAT " + driverID, Toast.LENGTH_SHORT).show();
    }
}

Another option is to use a ValueEventListener on the driverId location itself.

Upvotes: 2

Related Questions