There are two parts to this problem:
- Counting the number of messages
- Tracking what a user has read
Counting the number of messages
Assuming you are using the Firebase Realtime Database or Cloud Firestore, there are two typical approaches to counting:
- Load the unread messages and count them client-side.
- Keep a counter of the messages in the database, and update that every time you read/write a message.
Counting the messages client-side is easiest to implement, so typically what inexperienced developers start with. When the number of messages is low, that works fine. But as the number of messages grows, you'll be download more and more data.
At that point you'll switch to keeping a counter in the database and updating that on every write/delete operation. This duplicates data, so is typically something that developers with a background in relational databases struggle with. But it is the most common approach.
You can update the counter client-side, or use a server-side approach such as this example of maintaining counters in Cloud Functions.
Tracking what the user has read
To know how many unread messages a user has, you need to know what the user has already read. Here again, there are two common approaches:
- Track each individual message the user has read.
- Track the ID of the most recent message the user has read.
Tracking the individual messages sounds most correct, so I see this being done a lot. I also see developers struggling with it, since it involves a lot of book keeping. It's definitely possible, but I'd recommend starting with a simpler approach...
Chat apps deal with (chronological) sequences of messages. If you know the ID of the latest message that the user has seen, you could assume that the user has also seen all messages that are older than that.
Say that I track the timestamp of the last message you read, and it's 1535725374298
. I can now query the chat to only retrieve messages newer than that:
firebase.database()
.ref("chat")
.child(chatId)
.orderByChild("timestamp")
.startAt(1535725374298)