如何使用 addChildEventListener 仅获取在 Firebase 中修改过的数据?

How can I get only data that has been modified in Firebase using addChildEventListener?

我认为问题出在我的查询上,因为我尝试查询但它总是 returns Firebase 中的所有数据。我只想要标记为黄色的数据,在本例中就是已修改的数据。

求问:AreaRisco是静态key,而Brazil, Sao Paulo, Itaim Bibi, id是可变key,我只想获取修改后的key;

我的查询:

queryAreaRisco = firebaseDatabase.getReference("AreaRisco").orderByKey().limitToLast(1);

我的 ChildEventListener:

 private void lerAreasRisco() {

    final ArrayList<Geofence> finalGeofences = new ArrayList<>();

    queryAreaRisco.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            Log.i ("GEOFENCE/TESTE", "adicionou um filho");


        }

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


            Log.i ("GEOFENCE/TESTE", "mudou um filho - "+ results);
            Log.i ("GEOFENCE/TESTE-refs", String.valueOf(dataSnapshot));


            finalGeofences.clear();
            for (DataSnapshot areasRisco : dataSnapshot.getChildren()) {
                Log.i("GEOFENCE/TESTE - AREASR", areasRisco.getKey());
                if (!dataSnapshot.hasChildren()){
                    return;
                }


                for (DataSnapshot pais: areasRisco.getChildren()){
                    if (!pais.hasChildren()){
                        return;
                    }
                    Log.i("GEOFENCE/TESTE - CIDADE", pais.getKey());
                    Log.i ("GEOFENCE/TESTE", String.valueOf(pais.getRef()));
                    for (DataSnapshot cidade: pais.getChildren()){
                        if (!cidade.hasChildren()){
                            return;
                        }
                        Log.i ("GEOFENCE/TESTE", String.valueOf(cidade.getRef()));
                        chaveOcorrencia = cidade.getKey();
                        Centro_lat = (Double) cidade.child("Centro_lat").getValue();
                        Centro_lng = (Double) cidade.child("Centro_lng").getValue();
                        tipo = (String) cidade.child("Tipo").getValue();
                        Log.i("AREARISCO", String.valueOf(cidade));
                        Status = (Boolean) cidade.child("Status").getValue();
                        numero_Ocorrencia = (Long) cidade.child("numero_Ocorrencia").getValue();
                        pontoMaisDistanteLat = (Double) cidade.child("pontoMaisDistanteLat").getValue();
                        pontoMaisDistanteLng = (Double) cidade.child("pontoMaisDistanteLng").getValue();
                        if (!Status) {
                            continue;
                        }
                        ArrayList<Ocurrency> ocorrencias = new ArrayList<>();
                        for (DataSnapshot Ocorrencias : cidade.child("OcorrenciadaArea").getChildren()){
                            Ocurrency ocurrency = Ocorrencias.getValue(Ocurrency.class);
                            ocorrencias.add(ocurrency);
                        }
                        AreaRisco areaRisco = new AreaRisco();
                        areaRisco.setCentro_lat(Centro_lat);
                        areaRisco.setCentro_lng(Centro_lng);
                        areaRisco.setOcorrenciadaArea(ocorrencias);
                        areaRisco.setTipo(tipo);
                        areaRisco.setNumero_Ocorrencia(numero_Ocorrencia);
                        areaRisco.setPontoMaisDistanteLng(pontoMaisDistanteLng);
                        areaRisco.setPontoMaisDistanteLat(pontoMaisDistanteLat);
                        areaRisco.setStatus(Status);
                        finalGeofences.add(
                                new Geofence.Builder()
                                        .setRequestId(String.valueOf(chaveOcorrencia))
                                        .setCircularRegion(areaRisco.getCentro_lat(),
                                                areaRisco.getCentro_lng(),
                                                50)
                                        .setExpirationDuration(5000)
                                        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                                                Geofence.GEOFENCE_TRANSITION_EXIT)
                                        .build()
                        );


                        Log.i("GEOFENCE/TESTE", "geofence adicionado para notificação");
                        Log.i("GEOFENCE/TESTE", chaveOcorrencia);
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Status) {
                            createAreaRisco(areaRisco, mMap);
                        }


                    }
                }
                break;
            }
            addGeofences(getGeofencingRequest(finalGeofences), getGeofencePendingIntent());
        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
            Log.i ("GEOFENCE/TESTE", "removeu um filho");
        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

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

        }
    });
}

你不应该在 firebase 数据库中嵌套这么多。您可以阅读此文档以了解如何创建结构:

https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html

这行代码:

queryAreaRisco = firebaseDatabase.getReference("AreaRisco").orderByKey().limitToLast(1);

将检索 AreaRisco 下的最后一个密钥,因此如果您有:

AreaRisco
    Brasil
       SaoPaolo
           Itaim bibi
              id
           Jardim Regina
              id
    France
      Paris
        Paris Bibi
             id
        Paris regina
             id

使用上面的代码,因为您使用了 limitToLast(1),它将 return France 下的所有数据。您需要将结构更改为以下内容:

AreaRisco
  Itaim bibi
     randomid
         name : brasil
  Jardim Regina
     randomid1
          name : brasil

那么您上面的查询将起作用,并会为您提供最新的 ID。