Los datos extraídos de FirebaseDatabase se muestran en 3 AlertDialogs separados en lugar de uno
Estoy buscando algunos datos de FirebaseDatabase
y luego ponerlos en una array
y luego tratando de mostrarlos en una List
que está en un AlertDialog
personalizado.
Aquí está el código:
- Implementar una función de recibo de lectura en la aplicación de mensajería de grupo de Firebase
- Cómo utilizar el adaptador de lista de Firebase
- Permiso de Firebase negado Error
- Firebase: Base de datos escribir antes de iniciar sesión
- Manejando keepSynced () mientras está en segundo plano en Android y con FCM
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); uProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { if (dataSnapshot != null) { Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); ArrayList<String> l = new ArrayList<String>(); l.add(newD.get("lol").substring(30)); String names[] = l.toArray(new String[0]); AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); LayoutInflater inflater = getLayoutInflater(); View convertView = inflater.inflate(R.layout.dialog_list, null); alertDialog.setView(convertView); alertDialog.setTitle("title"); ListView lv = (ListView) convertView.findViewById(R.id.lv); ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); lv.setAdapter(adapter); alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); alertDialog.show(); } else { Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show(); } } ... ... }); } });
Aquí está la estructura de la base de datos:
app -child -anotherChild -yetAnotherChild -inaccessibleChild -someChild: "value" -lol: "value"
No puedo usar valueEventListener()
aquí, ya que no tengo acceso a inaccessibleChild
. El inaccessibleChild
aquí es el uid
de los otros usuarios que siguieron a un usuario en particular. ¿Cómo puedo acceder allí uid
?
El problema es que los datos se obtiene pero en lugar de ser mostrado en una lista en un AlertDialog
, se está mostrando uno a uno en 3 AlertDialog
separado.
¿Qué está pasando mal aquí?
Por favor hagamelo saber.
- Esperaba un mapa mientras se deserializaba, pero obtuvo una clase java.lang.Long
- FirebaseRecyclerAdapter con vista vacía
- Firebase RecyclerVisualización infinita
- ¿Sólo rellenar viewHolder con mensajes recuperados de la base de datos?
- Firebase android ¿Cómo evitar que FirebaseRecyclerAdapter se actualice automáticamente?
- Integración Algolia Firebase y Android
- Agregar más información de usuario con firebase
- Lista de recuperación de usuarios de Firebase Authentication
Las transacciones de Firebase son asíncronas así que su línea inicial para agregar los 3 niños sucede después de que usted fije su oyente, por lo tanto su llamada de llamada se llama 3 veces. (Haciendo 3 diálogos).
Mueva esta línea fuera del clic de clic:
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
Entonces cuando usted agrega el oyente de debajo (dentro del tecleo) debe ser aceptable
query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Cree y muestre el AlertDialog antes de llamar .addChildEventListener ()
A continuación, utilice dentro de addChildEventListener llamar a notifyDatasetChanged () después de descargar los datos apropiados. No cree el AlertDialog dentro del addChildEventListener
Puede utilizar las consultas de Firebase para limitar los datos descargados por un oyente.
query.orderByChild("someChild").limitToLast(1).addChildEventListener(...
@ Blundell tiene la idea de resolver su problema. Sólo quiero sugerirle un enfoque similar con addValueEventListener
.
El detector de eventos de valor se disparará una vez para el estado inicial de los datos y, a continuación, cada vez que cambie el valor de esos datos.
Necesita mover la consulta firebase de la función onClick
. Así que su consulta podría ser así.
// Declare the variable names as public private String names[]; private void addFirebaseListener() { ref = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); ref. userRef.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); ArrayList<String> l = new ArrayList<String>(); l.add(newD.get("lol").substring(30)); names[] = l.toArray(new String[0]); // Call notifyDataSetChanged each time your array gets updated adapter.notifyDataSetChanged(); } @Override public void onCancelled(FirebaseError error) { } }); }
Ahora escriba una función para mostrar el ListView
en el AlertDialog
// Declare the adapter as public and initialize it with null private ArrayAdapter<String> adapter = null; private void showListInDialog() { AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); LayoutInflater inflater = getLayoutInflater(); View convertView = inflater.inflate(R.layout.dialog_list, null); alertDialog.setView(convertView); alertDialog.setTitle("title"); ListView lv = (ListView) convertView.findViewById(R.id.lv); if(adapter == null) adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); // Now set the adapter lv.setAdapter(adapter); alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { alertDialog.dismiss(); } }); alertDialog.show(); }
Ahora, dentro de la función onCreate
, onCreate
debe configurar el oyente de Firebase y luego establecer la función onClick
esta manera.
uProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showListInDialog(); } });
@Hammad Pruebe este código modificado basándose en su requisito.
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); AlertDialog alertDialog; ArrayList<String> l; uProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { if (dataSnapshot != null) { Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); if(l == null) { l = new ArrayList<String>(); } l.add(newD.get("lol").substring(30)); String names[] = new String[l.size()]; for(int length=0; length < l.size(); l++) { names[length] = l.get(length); } if(alertDialog == null) { alertDialog = new AlertDialog.Builder(Activity.this).create(); LayoutInflater inflater = getLayoutInflater(); View convertView = inflater.inflate(R.layout.dialog_list, null); alertDialog.setView(convertView); alertDialog.setTitle("title"); ListView lv = (ListView) convertView.findViewById(R.id.lv); } ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); lv.setAdapter(adapter); alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); if(!alertDialog.isShowing()) { alertDialog.show(); } } else { Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show(); } } ... ... }); } });
Poner límite cuando estás usando valueEventListener
o addChildEventListener
. Me gusta esto,
int limit = 100; databaseRef.child("chats").limitToLast(limit).addValueEventListener(listener);
Y siempre eliminar el oyente cuando haya hecho con su trabajo relacionado con firebase. Me gusta esto,
databaseRef.child("chats").limitToLast(limit).removeEventListener(listener);
Gracias.
ChildEventListener childEventListener = new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
Todos los derechos reservados
Recuperar listas de elementos o escuchar las adiciones a una lista de elementos. Esta devolución de llamada se activa una vez para cada hijo existente y, a continuación, cada vez que se agrega un nuevo hijo a la ruta de acceso especificada. El DataSnapshot pasado al oyente contiene los datos del nuevo hijo.
** /
} @Override public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey()); } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey()); } @Override public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) { Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey()); } @Override public void onCancelled(DatabaseError databaseError) { }
}; Ref.addChildEventListener (childEventListener); Usando ChildEventListener onChildAdded son llamadas por niño que tiene en ese nodo. Significa que su código se ejecuta 3 veces para que el diálogo aparezca 3 veces.
Este es el problema Así que la solución es:
Si bien el uso de ChildEventListener es la forma recomendada de leer listas de datos, hay situaciones en las que es útil adjuntar un ValueEventListener a una referencia de lista.
Adjuntar un ValueEventListener a una lista de datos devolverá toda la lista de datos como un solo DataSnapshot, que luego se puede hacer un bucle para acceder a los niños individuales.
Incluso cuando sólo hay una coincidencia para la consulta, la instantánea sigue siendo una lista; Sólo contiene un solo elemento. Para acceder al elemento, debe realizar un bucle sobre el resultado:
inaccessibleChild.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) { //here you can access the each child of that node. } } @Override public void onCancelled(DatabaseError databaseError) { // Getting Post failed, log a message Log.w(TAG, "loadPost:onCancelled", databaseError.toException()); // ... }
});
Bueno, ninguna de las respuestas anteriores realmente ayudó, aunque la respuesta de Linxy es correcta, lo vi después de resolver el problema.
Mover todo el código y escribir sólo esta línea: alertDialog.show();
Dentro de setOnClickListener()
mejorando mi código a esto:
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild"); query.orderByChild("someChild").addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { if (dataSnapshot != null) { Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue(); ArrayList<String> l = new ArrayList<String>(); l.add(newD.get("lol").substring(30)); String names[] = l.toArray(new String[0]); AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this); LayoutInflater inflater = getLayoutInflater(); View convertView = inflater.inflate(R.layout.dialog_list, null); alertDialog.setView(convertView); alertDialog.setTitle("title"); ListView lv = (ListView) convertView.findViewById(R.id.lv); ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names); lv.setAdapter(adapter); alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { } }); } else { Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show(); } } ... ... }); uProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { alert11.show(); } });
De todos modos, me gustaría dar las gracias a todos los que respondieron a esta pregunta.
Paz.
- Clase hijo de EditText se ve diferente a la normal EditText en Android 4
- ¿Cómo detectar la salida de la aplicación en android?