Обнаружение изменения значения с помощью firebase ValueEventListener

Я пытаюсь обнаружить изменение значения из моей базы данных Firebase. Вот мой код для инициализации 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);

Проблема возникает, когда я хочу вызвать этого слушателя в своей деятельности. Я пытался с этим:

destinationListener.getValueEventListener().onDataChange(REQUIRED_SNAPSHOT);

Я не знаю, как я могу получить снимок данных, который требуется для onDataChange. Я хотел бы, чтобы эта работа работала с ValueEventListener, а не с ChildEventListener, если это возможно. Однако я не совсем уверен, что это правильный способ обнаружения изменения значения. Если есть какой-либо другой способ, который будет работать правильно, я хотел бы знать об этом.


person Milisav Puce Drobnjakovic    schedule 10.04.2020    source источник
comment
Вы не можете создать свой собственный DataSnapshot. Зачем вам это нужно?   -  person Frank van Puffelen    schedule 10.04.2020
comment
Поскольку мне нужен снимок в качестве параметра для вызова функции destinationListener.getValueEventListener().onDataChange(REQUIRED_SNAPSHOT); (Я назвал его REQUIRED_SNAPSHOT, потому что не знаю, что там должно быть). Однако, если вы знаете какой-либо другой способ сделать это, было бы неплохо, если бы вы могли помочь :)   -  person Milisav Puce Drobnjakovic    schedule 10.04.2020
comment
Это похоже на проблему XY. Зачем вам нужно делать этот вызов в вашем коде? У меня никогда не было необходимости вызывать слушателей самостоятельно, и я полагался только на Firebase для их вызова.   -  person Frank van Puffelen    schedule 10.04.2020
comment
Ссылаясь на ваш ответ здесь: вызывать valueeventlistener firebase программно в android"> stackoverflow.com/questions/51367944/ Я пытался реализовать его в своем приложении. Тем не менее, я снова говорю, что я не уверен, что это правильный подход, но я готов узнать, как определить, когда конкретное значение в базе данных firebase изменилось. Спасибо!   -  person Milisav Puce Drobnjakovic    schedule 11.04.2020
comment
Это предполагает, что у вас есть снимок предыдущих данных. Как сказано в моем первом комментарии, вы не можете создать снимок самостоятельно.   -  person Frank van Puffelen    schedule 11.04.2020
comment
Хорошо, я понял. Итак, не могли бы вы рассказать мне, как я могу прослушать изменение определенного значения в базе данных firebase?   -  person Milisav Puce Drobnjakovic    schedule 11.04.2020


Ответы (1)


В базе данных Firebase Realtime нет ничего, что могло бы сообщить вам, какие конкретные данные в моментальном снимке изменились в методе onDataChange.

Если вы хотите узнать, какое конкретное свойство было изменено, вам необходимо:

  1. Сохраните снимок, полученный в onDataChange, в поле.
  2. При вызове onDataChange сравните данные в новом снимке с данными в поле.

Допустим, у вас есть ссылка на узел в вашем JSON, и под этим узлом находится свойство status, и вы хотите как прослушать весь узел, так и определить, изменился ли status.

Вы бы сделали это с чем-то вроде:

// 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
    }
});

person Frank van Puffelen    schedule 11.04.2020
comment
Большое тебе спасибо. Теперь я могу обнаружить изменение значения! - person Milisav Puce Drobnjakovic; 11.04.2020
comment
Не забудьте удалить ValueEventListener из DatabaseReference, когда он больше недействителен (например, onDestroy() вашей активности или фрагмента) - person javmarina; 07.08.2020