recyclerview recycler firestore auth android firebase android-recyclerview firebase-database firebaseui

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!