java - guardar - query firebase android
Firebase: intentando recuperar los datos de cada usuario en una lista (1)
Cada usuario de mi aplicación puede enviar y recibir solicitudes de amistad. Cuando el usuario verifica las solicitudes de sus amigos, quiero que la aplicación revise a cada usuario que le envió una solicitud de amistad y que recupere su información de Realtime Database
.
Este es mi código para lograr esto:
public void check_For_Friends_And_Requests(){
String loggedUser=SaveSharedPreference.getLoggedEmail(getApplicationContext());
final DatabaseReference mDatabase= FirebaseDatabase.getInstance().getReference();
final DatabaseReference userRef=mDatabase.child("Users").child(loggedUser);
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
final List<User> friendRequestsReceived_UserList=new ArrayList<>();
for (DataSnapshot postSnapshot: dataSnapshot.child("friend_requests_received").getChildren()) {
final String senderEmail=postSnapshot.getKey();
Toast.makeText(getApplicationContext(),
senderEmail, Toast.LENGTH_SHORT).show();
if (senderEmail!=null){
mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Toast.makeText(getApplicationContext(),
dataSnapshot.child("name").getValue(String.class), Toast.LENGTH_SHORT).show();
friendRequestsReceived_UserList.add(
new User(
senderEmail,
dataSnapshot.child("name").getValue(String.class),
dataSnapshot.child("level").getValue(Integer.class),
dataSnapshot.child("skill").getValue(Double.class)));
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
UserListAdapter friendRequestsReceived_Adapter =
new UserListAdapter(getApplicationContext(),
R.layout.friend_requests_received_listview_row,
friendRequestsReceived_UserList);
friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter);
}
else
connectionErrorGoToMain();
}
@Override
public void onCancelled(DatabaseError databaseError) {
connectionErrorGoToMain();
}
});
}
Tengo en este código 2 ValueEventListeners
. Agrego la información del usuario a la lista en el interno. El problema es que la lista está vacía al final de este proceso.
Me gustaría completar una vista de lista con esta información usando estas líneas:
UserListAdapter friendRequestsReceived_Adapter =
new UserListAdapter(getApplicationContext(),
R.layout.friend_requests_received_listview_row,
friendRequestsReceived_UserList);
friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter);
Cuando los coloco dentro del listener innner, funciona bien, pero no quiero configurar el adaptador para cada usuario en la lista, solo después del ciclo for
.
Adjunto una captura de pantalla con la estructura de mi base de datos (no necesito obtener todos los parámetros):
La lista está vacía porque declaras friendRequestsReceived_UserList
fuera del onDataChange()
interno onDataChange()
. Esto sucede debido al comportamiento asincrónico del método onDataChange()
que se onDataChange()
antes de agregar esos nuevos objetos a la lista. Entonces, para resolver esto, simplemente mueva la declaración de la lista dentro del onDataChange()
interno onDataChange()
como este:
if (senderEmail!=null){
mDatabase.child("Users").child(senderEmail).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<User> friendRequestsReceived_UserList=new ArrayList<>(); //Moved here
Toast.makeText(getApplicationContext(), dataSnapshot.child("name").getValue(String.class), Toast.LENGTH_SHORT).show();
friendRequestsReceived_UserList.add(
new User(
senderEmail,
dataSnapshot.child("name").getValue(String.class),
dataSnapshot.child("level").getValue(Integer.class),
dataSnapshot.child("skill").getValue(Double.class)));
UserListAdapter friendRequestsReceived_Adapter =
new UserListAdapter(getApplicationContext(), R.layout.friend_requests_received_listview_row, friendRequestsReceived_UserList);
friendRequestsReceived_ListView.setAdapter(friendRequestsReceived_Adapter);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Como probablemente vea, configuro el adaptador también dentro del método interno. Si desea usar esa lista fuera de onDataChange()
sugiero que lea mi respuesta de esta publicación .