Search code examples
javaandroidfirebasefirebase-realtime-databaseevent-listener

Detect value change with firebase ValueEventListener


I am trying to detect value change from my Firebase Database. Here is my code for initializing the ValueEventListener:

valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            try {
                String customerLocation = String.valueOf(dataSnapshot.getValue());
                Point customerPoint = locationFounder.getPoint(customerLocation);

                if (customerPoint != null) {
                    databaseReference.child("isActive").addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                            boolean isActive = Boolean.valueOf(String.valueOf(dataSnapshot.getValue()));

                            displayPopUp(isActive, customerPoint, customerLocation);
                        }

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

                        }
                    });
                }
            } catch (Exception e) {
                Log.d("Listener",e.toString());
            }
        }

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

        }
    };
    destinationReference.addValueEventListener(valueEventListener);

Problem occurs when I want to call this listener in my activity. I've been trying with this:

destinationListener.getValueEventListener().onDataChange(REQUIRED_SNAPSHOT);

I do not know how can I get datasnapshot which is required for onDataChange. I would like to get this work with ValueEventListener, not ChildEventListener, if possible. However, I am not pretty sure that this is the right way of trying to detect value change. If there is any other way that will work properly, I'd like to know about it.


Solution

  • There is nothing built to the Firebase Realtime Database to tell you what specific data under the snapshot has changed in the onDataChange method.

    If you want to know what specific property has change, you'll need to:

    1. Keep the snapshot that you get in onDataChange in a field.
    2. When onDataChange gets called, compare the data in the new snapshot with the data in the field.

    Say that you have a reference on a node in your JSON, and under that node is a status property, and you want to both listen to the entire node, and detect if the status has changed.

    You'd do that with something like:

    // Add a field to your class to keep the latest snapshot
    DataSnapshot previousSnapshot;
    
    // Then add your listener
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            bool wasActive = false;
            if (previousSnapshot != null && previousSnapshot.child("status").exists()) {
                wasActive = dataSnapshot.child("status").getValue(Boolean.class);
            }
            boolean isActive = dataSnapshot.child("status").getValue(Boolean.class);
    
            if (isActive <> wasActive) {
                ... the user's status changed
            }
    
            previousSnapshot = dataSnapshot;
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            throw databaseError.toException(); // never ignore errors
        }
    });