I'm creating a chat section for android apps. By using Google Firebase. Following task already completed
Create chat node 2. Separate particular chat thread using two users information. 3. Read all message for single chat thread.
Now my question is below. 1. How to retrieve last message by single chat thread. 2. How to create a database where i can get counter of unread message counter.
Attachment of my chat database and objective below.
Current objective.
Already done.
Firebase database architecture.
Now how it will be easier for me to create database for make solution this problem.
Firebase has it's own example project for building a Chat platform, Firechat. The project is well explained in it's doc. The data structure they used can be seen at the end of the doc. You can use their data structure. But for your case, you probably don't have any moderator, so we can make it a little simple than that.
So, you can organize it like this:
main-data
|__messageThread (all data about msgs)
| |__threadId (unique id for msg thread)
| |__chatId (unique id for chat msgs)
| |__userId
| |__userName
| |__chatMessage
| |__chatTimestamp
|
|__messageThreadMetadata
| |__threadId
| |__createdAt
| |__createdByUserId
| |__threadId
| |__threadName
| |__threadType (public/private)
| |__lastChatId (id for last chat, use this to lookup in messageThread)
|
|__users
| |__userId
| |__userId
| |__userName
| |__activeThreads (list of ids of active threads used by user)
|
|__unseenMsgCountData
| |__threadId
| |__userId
| |__unseenMsgCount
To get back to your question:
How to get last message in a thread? Please use the node lastChatId in a thread and use it to look up the respective chatMessage.
How to get unseen message count in a thread for an user? This is a data that is subjective to each thread and each user. A same thread may have two or more users, each having different unseen message count. So, you can use unseenMsgCountData where you can check across a threadId and userId. Whenever anyone posts a chat, increment the unseen msg counter by 1 in that thread for other users, who has the chat thread closed (use the activeThreads list from users to track whether he is actively in the thread or not). DO NOT increase the counter for him though, this msg is not his own unseen msg). When any other user opens that thread, reset the value to zero for him.
Hope this helps. Knock here if any further explanation or help is needed.
this is my workaround.
as you can see i am making two reference one for message and second recent is for user list.
whenever i tap on user list and open my chat page, In my chat page i m checking condition for receiver id and send status and count to recent refrence in onCreate() of chat page, like this.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
uid = pref.getString("uid", null);
sender_name = pref.getString("first_name", null);
Bundle bundle = getIntent().getExtras();
if(bundle != null && !bundle.isEmpty()){
recevier_name = bundle.getString("uname");
receiver_id = bundle.getString("UserId");
}else {
recevier_name = "Admin";
receiver_id = "1";
}
chat_date = listAdapter.SIMPLE_DATE_FORMAT.format(new Date().getTime());
if (Integer.parseInt(uid) < Integer.parseInt(receiver_id)) {
value = String.valueOf(uid + "--*--" + receiver_id);
} else {
value = String.valueOf(receiver_id+"--*--"+uid);
}
myRef1 = database.getReferenceFromUrl("https://firebaseio.com/messages/"+value);
myRef2 = database.getReferenceFromUrl("https://firebaseio.com/recents/"+value);
myRef2.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Map map1 = (Map) dataSnapshot.getValue();
if(map1 != null){
String rec_id = (String) map1.get("recever_id");
if(rec_id.equals(uid)){
myRef2.getRef().child("count").setValue("0");
myRef2.getRef().child("status").setValue("online");
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
getChat();
}
so everytime when i open my chat my status is online if receiver_id is my_id.
now in chat button click i m checking for count if status is not online, like this.
private ImageView.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(v==enterChatView1)
{
message_text = chatEditText1.getText().toString();
final Map<String, String> map = new HashMap<String, String>();
map.put("sender_id", uid );
map.put("recever_id", receiver_id);
map.put("sender_name", sender_name);
map.put("recevier_name", recevier_name);
map.put("text", message_text);
map.put("text_id", uid);
map.put("date", chat_date);
myRef1.push().setValue(map);
// myRef2.setValue(map);
// sendMessage(chatEditText1.getText().toString(), chat_date, UserType.OTHER);
myRef2.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Map map1 = (Map) dataSnapshot.getValue();
if(map1 != null){
String status = (String)map1.get("status");
if(map1.containsKey("count")){
if(!status.equals("online")) {
String count = (String) map1.get("count");
int val = Integer.parseInt(count);
map.put("count", String.valueOf(++val));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "YES" + val);
}else {
map.put("count", String.valueOf(0));
map.put("status", "online");
myRef2.setValue(map);
Log.d("VALUE", "No");
}
}else {
map.put("count", String.valueOf(1));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "No");
}
}else {
map.put("count", String.valueOf(1));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "first time");
}
}else {
map.put("count", String.valueOf(1));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "first time");
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
chatEditText1.setText("");
}
};
and at last when you close your chat page. add status offline to recent in onBackPress() event, like this.
@Override
public void onBackPressed() {
myRef2.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Map map1 = (Map) dataSnapshot.getValue();
if(map1!= null){
String rec_id = (String) map1.get("recever_id");
if(rec_id.equals(uid)){
myRef2.getRef().child("count").setValue("0");
myRef2.getRef().child("status").setValue("offline");
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
finish();
this.overridePendingTransition(R.anim.left_in,
R.anim.left_out);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With