I'd like to implement a 'Seen' feature in my Firebase group messaging app. Can you kindly advise the best and most efficient approach to take (working code will be appreciated)? For example, the app would show "Seen by 6" or "Seen by 15" on a group message.
Here's my project: https://github.com/firebase/friendlychat/tree/master/android
Here's the MainActivity: https://github.com/firebase/friendlychat/blob/master/android/app/src/main/java/com/google/firebase/codelab/friendlychat/MainActivity.java
To achieve this, you need to add another node in your Firebase database named seenBy
which must be nested under each messageId
in meassage
section. Your database should look like this:
Firebase-root
|
---- messages
|
---- messageId1
|
---- meessage: "Hello!"
|
---- timestamp: 1498472455940
|
---- seenBy
|
---- userUid1: John
|
---- userUid2: Mary
|
---- userUid3: George
Every time a new user opens a meesage, just add the uid
and the name
as explained above.
To implement Seen by 6
option, it's very easy. You just need to create a listener
and use getChildrenCount()
method like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference seenByRef = rootRef.child("messages").child(messageId).child("seenBy");
ValueEventListener eventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
long seenBy = dataSnapshot.getChildrenCount();
Lod.d("TAG", "Seen by: " + seenBy);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
seenByRef.addListenerForSingleValueEvent(eventListener);
To know whether a message has been opened or not, you need to add another field to your user section in which you need to add a boolean
with the default value of false
. This new section should look like this:
Firebase-root
|
---- users
|
---- userId1
|
---- meessages
|
---- messageId1: false
|
---- messageId2: false
|
---- messageId3: false
When a users opens that message, just set the value of that particular message from false
to true
, which means that the particular message has been opened. This is the code:
DatabaseReference openedRef = rootRef.child("users").child(userId).child("meessages").child("messageId1");
openedRef.setValue(true);
When you create a message, use push()
method on the reference like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference messageRef = rootRef.child("meessages").push();
String messageKey = messageRef.getKey();
Having this key, you can use it in your DatabaseReference
. In the same way you can use for the userId.
Hope it helps.
Yeah it is possible, You can add a child seen_by
to the message, whenever user views the message append the viewers userId to the seen_by
, then by retrieving the userID
and you can count the number of viewers and also you can see the list of viewed members too. The format should be
message:{
FirebaseKey:{
message:"hi",
timestamp:1498472455940,
seen_by:"abc,def,ghi" //users UID
}
}