如何使用 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。
我认为问题出在我的查询上,因为我尝试查询但它总是 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。