Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Aplicación de chat que utiliza Firebase: Recibe notificación cuando recibe un nuevo mensaje – Android

Estoy desarrollando una aplicación de chat utilizando Base de datos en tiempo real Firebase. He podido enviar y recibir mensajes correctamente. Ahora, quiero implementar la notificación cada vez que se reciba un mensaje nuevo. Para ello, he creado un Service que escucha los cambios de base de datos con ChildEventListener y crea notificaciones. El problema es que estoy creando la notificación en el método onChildAdded y este método dispara tanto para el nodo existente en la base de datos y el nuevo. Esto está causando que la notificación se cree varias veces para el mismo mensaje siempre que el usuario navegue hacia adelante y hacia atrás desde la aplicación.

Aquí es cómo lo estoy implementando:

  • Cómo agregar casillas de verificación dinámicamente en android
  • ¿Cómo cambiamos MTP más fácilmente en un dispositivo Debug-Enabled Android 6.0?
  • Android: Cómo obtener un mapa OSM girado para llenar la pantalla completa
  • Tostadas simples de Android no se alinean correctamente
  • Cómo cargar archivos en la unidad de google con mi aplicación de Android
  • ¿Cómo puedo encontrar el tamaño máximo de textura para diferentes teléfonos?
  •  chatMsgsRef.orderByChild(FirebaseDBKeys.LOCATION_LAST_UPDATED).addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { ChatMessage message = dataSnapshot.getValue(ChatMessage.class); if (!message.getSenderId().equals(currentUserId)) { mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(NotificationsService.this) .setSmallIcon(R.drawable.message) .setContentTitle("New Message from " + message.getReceipientName()) .setContentText(message.getMessage()) .setOnlyAlertOnce(true) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); mBuilder.setAutoCancel(true); mBuilder.setLocalOnly(false); mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build()); } } @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) { } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { } @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) { } @Override public void onCancelled(DatabaseError databaseError) { } }); 

    ¿Cómo puedo implementar las notificaciones de la forma en que funciona en otras aplicaciones de chat como whatsapp, etc.?

  • No se pueden leer eventos periódicos del calendario android mediante programación
  • Quitar icono de la barra de acción xamarin
  • Google Maps de Google - marcador marcado abre una nueva actividad o una ventana más grande
  • Adición de Joda Time a Android Studio
  • ImageView src con el selector extraíble ignora el estado habilitado
  • ¿Hay un oyente para escuchar los cambios en el volumen en android?
  • 4 Solutions collect form web for “Aplicación de chat que utiliza Firebase: Recibe notificación cuando recibe un nuevo mensaje – Android”

    La forma correcta de hacerlo es tener un mensaje de datos push al cliente con el chat cuando hay una nueva conversación enviada a ellos.

    Esta entrada del blog explica cómo lograr esto. Básicamente, es necesario configurar un servidor para escuchar el chat ref firebase y enviar notificaciones push cuando se actualiza. De esta manera sus clientes pueden estar en la aplicación o fuera de la aplicación y seguir recibiendo el empuje.

    Si utiliza un servicio hay una serie de problemas potenciales.

    En primer lugar, tendrá que mantener el teléfono despierto. Esto agotará la batería.

    En segundo lugar, Android puede matar su servicio de fondo en cualquier momento, por lo que su aplicación puede dejar de funcionar de repente.

    En tercer lugar, con el modo Doze Android bloqueará la actividad de la red y evitará que su aplicación se ejecute en segundo plano.

    Se me ocurrió una mejor respuesta:

    Lo que quiere en este caso no es necesariamente conocer nuevos mensajes. Es para conocer mensajes UNREAD.

    Establezca un indicador de "lectura" en el objeto ChatMessage (o, a la inversa, tenga un valor en algún lugar que indique la marca de tiempo o ID del mensaje de lectura más reciente).

    Ahora, siempre que onChildAdded se dispare, compruebe si se lee == false. Si es así, muestre una notificación de que el mensaje no está leído (recuerde actualizar la notificación si existe, por lo que sólo se mostrará una notificación y mostrará la más reciente – oh, y recuerde también eliminar la notificación cuando el niño Se cambia para leer.)

    Si el usuario está utilizando la aplicación en varios dispositivos, comprobará correctamente el estado de lectura. Si lee el mensaje más reciente en un teléfono y luego va a la tableta, no mostrará la notificación de nuevo mensaje.

    Si lo desea, puede incluso utilizar esta funcionalidad para indicar que el destinatario le lee su mensaje.

    ¿Cómo sabes cuando se lee? Tal vez simplemente cuando se agrega en la pantalla. Tal vez usted se asegure de que está a la vista (no se desplaza por la pantalla) y es visible durante varios segundos.

    ¿Has probado addValueEventListener?

    https://www.firebase.com/docs/android/guide/retrieving-data.html#section-start

     // Get a reference to our posts Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"); // Attach an listener to read the data at our posts reference ref.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { System.out.println(snapshot.getValue()); } @Override public void onCancelled(FirebaseError firebaseError) { System.out.println("The read failed: " + firebaseError.getMessage()); } }); 

    "Este método se llamará siempre que se agreguen nuevos datos a nuestra referencia de Firebase, y no necesitamos escribir ningún código extra para que esto suceda".

    EDIT: "Se activa una vez con los datos iniciales y de nuevo cada vez que cambia los datos." No lo he probado, pero mi pensamiento sería establecer una bandera cuando el método dispara la primera vez. Entonces, siempre que se establezca el método y ese indicador (en otras palabras, la segunda vez, tercera vez, cuarta vez, etc.) obtendrá el objeto más reciente de la instantánea.

    Una combinación de la respuesta de @Chad Shultz y su código original, con algunas adiciones estructurales de la base de datos.

    Usted, como lo intentó originalmente, usará una consulta

     chatMsgsRef.orderByChild(...) 

    Sin embargo, cambie la estructura de datos para tener el siguiente diseño

     >root > users > userID_001 > chats > chat_001:true > userID_002 > chats > chat_001:true > chats > chat_001 > participants > userID_001:true > userID_002:true > messages > msg_001 > sender:"userID_001" > text:"some message" > time:"some time" > message_read_states > chat_001 > msg_001 > userID_001:true > userID_002:false 

    Así que cada vez que se envía un mensaje, se empuja al nodo "mensajes". A continuación, el sistema obtiene todos los "participantes" y los empuja bajo el nodo "message_read_states" para ese chat / mensaje, con un valor de false para todos excepto para el remitente. Cuando alguien lee el mensaje, cambian su valor a verdadero allí.

    Ahora el Servicio debe determinar qué mensajes notificar a un usuario. El servicio colocará un escucha en message_read_states / chat_X y lo ordenará por el valor del campo secundario "userID_X" (dependiendo de quién sea el usuario actual). Haremos que la consulta sólo devuelva los ID de mensaje, para cada chat, para los que hay un valor "userID_X: false" debajo de él

    En este ejemplo, para "userID_002", la consulta devolverá "msg_001", pero para "userID_001" no devolverá nada, porque no se encuentra el valor requerido para esa clave (él / ella fue el remitente).

    La Consulta se construirá de la siguiente manera, dentro de su Servicio onStartCommand:

      //TODO: Get the ID of the chat the user is taking part in String chatID = "chat_001"; // Check for new messages FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); if (currentUser != null){ String UID = currentUser.getUid(); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); Query query = rootRef.child("message_read_states").child(chatID).orderByChild(UID).equalTo(false); query.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { String messageID = dataSnapshot.getKey(); //TODO: Handle Notification here, using the messageID // A datasnapshot received here will be a new message that the user has not read // If you want to display data about the message or chat, // Use the chatID and/or messageID and declare a new // SingleValueEventListener here, and add it to the chat/message DatabaseReference. } @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) { String messageID = dataSnapshot.getKey(); //TODO: Remove the notification // If the user reads the message in the app, before checking the notification // then the notification is no longer relevant, remove it here. // In onChildAdded you could use the messageID(s) to keep track of the notifications } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { } @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) { } @Override public void onCancelled(DatabaseError databaseError) { } }); } 

    Ahora, por supuesto, es muy probable que un usuario estará involucrado en varios chats. Tendrá que iterar sobre todos los chats asociados con el usuario, e implementar una consulta para cada chat.

    Fuente: Actualmente estoy trabajando en una aplicación Firebase con un sistema de chat

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.