I have a list of Firebase message objects, each of which may be updated before an activity is opened, at which point a Firebase ChildEventListener()
fires off (children are handled in onChildAdded()
).
The update uses a setValue()
on the status
field:
database.getReference("Messages").child(roomID).child(msgID).child("status").setValue("delivered");
The ChildEventListener()
fires off fine for all children when the activity is opened. However, for those children (messages) that had their status' updated before hand, they return null
for all fields except the status
field.
In the Firebase database, all fields are as they should be (non-null), so there is nothing wrong with the data.
Upon exiting the activity and re-entering, all children are returned in the ChildEventListener()
as they should be (no more null data returned).
In short, two ChildEventListener()
calls are required to return all the data for a child after a setValue()
is run on that child.
More code and context can be provided if required. Let me know.
Edit 1: here is the listener: (it is in onResume()
)
newMessageListner = myMessageRoomRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, String previousChildName) {
if (dataSnapshot.exists()) {
String messageKey = dataSnapshot.getKey();
Message messageClass = dataSnapshot.getValue(Message.class);
String messageUserID = messageClass.getUserId();
Log.d(TAG, "Message Key: " + messageKey);
Log.d(TAG, "Message Status: " + messageClass.getStatus());
Log.d(TAG, "Message User ID: " + messageUserID);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Edit 2: I call the getValue()
from sendNotification()
in my FirebaseMessagingService
private void sendNotification(RemoteMessage remoteMessage) {
//Intent intent = new Intent(this, StudentChatActivity.class);
String clickAction = remoteMessage.getData().get("click_action");
Intent intent = new Intent(clickAction);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
String roomID = remoteMessage.getData().get("ROOMID");
String origin = remoteMessage.getData().get("ORIGIN");
String msgID = remoteMessage.getData().get("MSGID");
Log.d(TAG, "Message data payload, roomID: " + roomID);
database.getReference("Messages").child(roomID).child(msgID).child("status").setValue("delivered");
intent.putExtra("ROOMID", roomID);
intent.putExtra("USERID", UserID);
intent.putExtra("USERNAME", UserName);
intent.putExtra("ORIGIN", origin);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.received_message);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.small_pickle)
.setContentTitle("FCM Message")
.setContentText(remoteMessage.getData().get("body"))
.setPriority(1)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
See Question&Answers more detail:
os