About receiving useQuery events
I have a question about useQuery. (This is a translation, so the wording may be awkward).
I'm developing a chat room. I'll give you an example to help you understand. I've created the following getMessages function to query messages per chat room.
export const getMessages = query({
args: { roomId: v.id(“rooms”) },
handler: async (ctx, args) => {
return await ctx.db
.query(“messages”)
.filter(q => q.eq(q.field(“roomId”), args.roomId))
.collect();
}
});
When a new message is inserted in a chat room with roomId A, users who are in chat room A will receive a newMessage event and see the new message.
Users in the chat room with roomId B should not see the new message, but the logs in the convex dashboard show that users in room B are also receiving getMessages events, meaning that as many getMessages logs are being generated as users who are currently viewing the chat screen, regardless of roomId.
In this case, we are receiving as many events as there are users in the chat room, is this normal behavior? Or am I making a mistake or missing something in my code?
I want to make sure that I only receive events that match the roomId.
11 Replies
Thanks for posting in <#1088161997662724167>.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.
- Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
- Use search.convex.dev to search Docs, Stack, and Discord all at once.
- Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI.
- Avoid tagging staff unless specifically instructed.
Thank you!
This query will only return messages with the provided roomId. Can you share where you're getting signals that this isn't happening? I know you mentioned Convex dashboard logs, just looking for more specifics to help troubleshoot. This query is using a filter instead of an index, so it will read more data than necessary, but the filter will keep any messages from other rooms from actually being returned.
Does not fix your problem, but side note, I'd recommend switching to an index.
First, I'm working with Next.js 14, Convex, and Convex Auth.
As you mentioned, on the client page using getMessages, only messages with the specific roomId are being returned.
However, let's say 4 users are on the chat page (using getMessages), but each is viewing a page with a different roomId. When a specific user performs a mutation for roomId A, getMessages should only update for the chat room matching that roomId. Consequently, the logs page in the dashboard should show the getMessages function only once, but as shown in the attached image, it appears 4 times.
To clarify, if only 1 user is viewing the chat page, the getMessages function appears once. But as the number of users viewing the chat page increases, the getMessages function in the dashboard logs increases proportionally - even when users are on pages with different roomIds.
On the client side, only messages with the same roomId are displayed, so other roomId messages are not actually shown. However, it seems unusual that the getMessages function is logged as many times as there are users in the dashboard logs.
I'm curious whether this is the original way Convex operates or if I'm misconfiguring something. If it's a misconfiguration, I'd appreciate hints about where I might be going wrong.
Yep, this is because you're not using indexes, so every getMessages query is doing a full table scan and has to rescan once the table changes.
Swap your filter for an index and you should see this stop
Indexes | Convex Developer Hub
Indexes are a data structure that allow you to speed up your
The issue was resolved by using an index. Since this is still in the early stages of development, I was planning to apply indexes later, but it seems they are essential. Thank you so much for your help. Have a great day!
To add slightly more info -- we'll re-execute queries when any of the underlying data changes (so in the case of using a
.collect
, when any document in that table changes), but only send a new query result to the client if the result has changed -- so a client loading the query for room B will not receive query results when messages are added for room A, but the query will re-execute (it'll just have the same result so we won't send an update to the client)
But yeah, this is a pretty perfect use case for an index 🙂If you’re doing early development and don’t want to use indexes, you can still not use indexes for now and just ignore the logs.
Now I can understand it clearly. Thank you!