android - firestore - FirebaseRecyclerAdapter''s populateViewHolder() se llama antes de que una clave que tiene ciertos valores se elimine por completo dando asà nullpointereception
firebase ui firestore (1)
Estoy usando FirebaseUI
de FirebaseRecyclerAdapter
en mi aplicación para buscar algunos datos de una referencia de FirebaseDatabase y mostrarlos en un RecyclerView
. Estoy completando esta tarea con éxito.
Aquí está mi código:
private void attachRecyclerViewAdapter() {
Query lastFifty = mDatabase.child(rID).limitToFirst(50);
mRecyclerViewAdapter = new FirebaseRecyclerAdapter<AModelClass, AModelClass.ViewHolder>(
AModelClass.class, R.layout.a_player_layout, APlayersModelClass.ViewHolder.class, lastFifty) {
@Override
protected void populateViewHolder(AModelClass.ViewHolder viewHolder, AsModelClass model, int position) {
String key = this.getRef(position).getKey();
aReference.child(requestID).child(key).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Map<String, String> map = (Map<String, String>) dataSnapshot.getValue();
pA = map.get("pName");
uA = map.get("pUrl");
// error on line below
String cLatS = map.get("cLat").trim();
currentLtAU = Double.parseDouble(cLatS);
String cLngS = map.get("cLng").trim();
currentLnAU = Double.parseDouble(cLngS);
viewHolder.setPName(pA);
viewHolder.setPUrl(uA);
viewHolder.setCurrentLatAU(String.valueOf(currentLtAU));
viewHolder.setCurrentLngAU(String.valueOf(currentLnAU));
} else {
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "Some error occurred. Please retry!", Snackbar.LENGTH_SHORT);
snackbar.show();
onBackPressed();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
aList.setAdapter(mRecyclerViewAdapter);
}
Aquí está la representación de la estructura de la base de datos:
-app
-requestID
-uniqueKey1
-key: value
-key: value
-cLat: value
-uniqueKey2
-key: value
-key: value
-cLat: value
El problema es que tan pronto como uniqueKey1
de la base de datos, se llama al código dentro del método populateViewHolder()
y los datos en uniqueKey1
no se eliminan por completo y, por lo tanto, aReference.child(requestID).child(key)
toma el uniqueKey1
nuevo, pero esta vez algunos de los datos, específicamente cLat
se eliminan de aquí y, por lo tanto, la aplicación falla al dar java.lang.NullPointerException: Attempt to invoke virtual method ''java.lang.String java.lang.String.trim()'' on a null object reference
error de java.lang.NullPointerException: Attempt to invoke virtual method ''java.lang.String java.lang.String.trim()'' on a null object reference
en la línea especificada en el código.
Lo que quiero saber es cómo puedo permitir que el código dentro de populateViewHolder()
uniqueKey1
solo cuando el uniqueKey1
junto con los datos debajo se elimine por completo y luego aReference.child(requestID).child(key)
solo tome uniqueKey2
(restante tecla (s)) como parámetro para cargar datos de nuevo y mostrar en recyclerview?
Bueno, creo que descubrí un camino.
Acabo de colocar algunas condiciones en el código.
Aquí está el código actualizado:
if (dataSnapshot.getValue() != null) {
if (dataSnapshot.hasChild("pName") && dataSnapshot.hasChild("pUrl") && dataSnapshot.hasChild("cLat") && dataSnapshot.hasChild("cLng")) {
Map<String, String> map = (Map<String, String>) dataSnapshot.getValue();
pA = map.get("pName");
uA = map.get("pUrl");
String cLatS = map.get("cLat").trim();
currentLtAU = Double.parseDouble(cLatS);
String cLngS = map.get("cLng").trim();
currentLnAU = Double.parseDouble(cLngS);
viewHolder.setPName(pA);
viewHolder.setPUrl(uA);
viewHolder.setCurrentLatAU(String.valueOf(currentLtAU));
viewHolder.setCurrentLngAU(String.valueOf(currentLnAU));
}
}
y ahora todo funciona perfectamente bien!