George Assan
George Assan

Reputation: 111

How to efficiently list recently active group chats for users without fan-out writes in 1000+ member groups?

I'm using a two-collection approach (userChats and chats) for quickly accessing a user's group chats as opposed to the use of an extremely long participant array of user IDs. However, I am struggling with efficiently showing which chats in listview in order of recent activity like the latest message.

Current Schema:

// Quick access to user's chats to avoid querying large participant arrays
userChats/{userId}/chats/{chatId} {
  joinedAt: Timestamp
}

// Main chat data
chats/{chatId} {
  lastMessageAt: Timestamp,
  participantCount: int,
  participants: {
    [userId]: true  // For membership checks
  }
}

The Problem:

When loading a user's chat list with pagination, I've hit a fundamental issue:

  1. If I order by joinedAt in userChats:
final userChats = await firestore
    .collection('userChats')
    .doc(userId)
    .collection('chats')
    .orderBy('joinedAt', descending: true)
    .limit(20)
    .get();

Issue: Active chats that the user joined long ago appear at the bottom of their paginated list, requiring users to scroll through potentially hundreds of chats to see new activity. There is the obvious point that 'joinedAt' is not lastMessageSent Time

  1. If I mirror lastMessageAt to userChats to order by recent activity:
userChats/{userId}/chats/{chatId} {
  joinedAt: Timestamp,
  lastMessageAt: Timestamp  // Mirror from main chat
}

Issue: Every new message requires updating all participants' userChats documents (1000+ writes per message).

Question:

What's the most efficient Firestore schema to show users their recently active chats while:

  1. Avoiding fan-out writes to all participants on each message
  2. Ensuring active chats appear at the top of the list regardless of when the user joined
  3. Supporting efficient pagination for users in hundreds of chats

Upvotes: 0

Views: 34

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 139019

Without having the lastMessageAt field inside the "chat" document, there is no way you can filter and order your chats. Firestore cannot perform such operation on non-existing fields or on fields that exist in some other parts of the database. It's true that to have such functionality you have to update the lastMessageAt field each time a new message is added in each chat, but it's a trade between having this functionality or not having it at all.

In such cases, I recommend you notice that Firebase has another similar scalable NoSQL real-time database which is called the Realtime Database. This database has a billing mechanism different from that of Firestore. So you’re charged for bandwidth and not for reads and writes you perform. So you might take this option into consideration.

Upvotes: 0

Related Questions