es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe alguna manera de guardar datos de una base de datos en tiempo real de Firebase sin obtener una variable nula?

Tengo una base de datos en tiempo real de Firebase y me gustaría recuperar algunos datos y ponerlos en un ArrayList.

ArrayList itemsArray;
List itemsList;

DatabaseReference shopRef;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shop);

itemsArray = new ArrayList<>();

shopRef = FirebaseDatabase.getInstance().getReference();

Query query = shopRef.child("shop");

query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Item item = new Item();
            item.setLogo(snapshot.child("Logo").getValue().toString());
            item.setName(snapshot.child("Name").getValue().toString());
            item.setDescription(snapshot.child("Description").getValue().toString());
            itemsArray.add(item);  //itemsArray está lleno

        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
    }
});

itemsList = itemsArray; // itemsArray es nulo

}

El problema es que después del listener, parece fácil de arreglar, pero no entiendo por qué el ArrayList es nulo.

El base de datos funciona correctamente.

La clase Item funciona correctamente.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código anterior es que el ArrayList itemsArray se está llenando de forma asíncrona dentro del ValueEventListener. Por lo tanto, cuando se ejecuta la línea itemsList = itemsArray, es probable que itemsArray siga estando vacío/nulo ya que el listener aún no ha terminado de obtener y llenar los datos.

    Para resolver este problema, una opción es mover cualquier operación que requiera que itemsArray esté lleno dentro del método onDataChange del listener. Aquí tienes un ejemplo:

    ArrayList<item> itemsArray;
    DatabaseReference shopRef;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shop);
    
        itemsArray = new ArrayList<>();
    
        shopRef = FirebaseDatabase.getInstance().getReference();
    
        Query query = shopRef.child("shop");
    
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    Item item = new Item();
                    item.setLogo(snapshot.child("Logo").getValue().toString());
                    item.setName(snapshot.child("Name").getValue().toString());
                    item.setDescription(snapshot.child("Description").getValue().toString());
                    itemsArray.add(item); // itemsArray ahora está lleno
                }
    
                // mueve cualquier operación que requiera que itemsArray esté lleno aquí
                // por ejemplo, crea itemsList a partir de itemsArray
                List<item> itemsList = new ArrayList<>(itemsArray);
                // o actualiza la interfaz de usuario con los datos de itemsArray
                updateUI(itemsArray);
            }
    
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
    }
    

    En este ejemplo, itemsList se crea dentro del método onDataChange después de que itemsArray se haya llenado. Cualquier otra operación que requiera que itemsArray esté lleno también debe ser movida dentro de este método.

Comments are closed.