How to limit requests to database
Unanswered
European anchovy posted this in #help-forum
European anchovyOP
I have a search input that allows users to search for profiles and click on one to create a new chat with them. It then uses a server function from my server component to insert the new chat into supabase. The issue is that the user can spam click the profile and create 2 chats with the same profile, which should not be allowed. I've tried to prevent this from happening with react useState or useTransition in the client, which worked before and I prevented the user from spamming messages, however for some reason it's not working now.
Server function:
Server function:
const createNewChat = async (participantId: Profile["id"]) => {
"use server";
const supabaseActionServer = createServerActionClient<Database>({
cookies,
});
// create a conversationId in conversations with type: direct_message (one-to-one chat)
const conversationId = uuidv4();
const { data: conversation, error: conversationError } =
await supabaseActionServer
.from("conversations")
.insert({ id: conversationId, type: "direct_message" });
// add current user and selected participant to chat
const { data: addCurrentUser, error: addCurrentUserError } =
await supabaseActionServer
.from("user_conversations")
.insert({ user_id: user.id, conversation_id: conversationId });
const { data: addParticipant, error: addParticipantError } =
await supabaseActionServer
.from("user_conversations")
.insert({ user_id: participantId, conversation_id: conversationId });
revalidatePath("/messages");
if (conversationError) throw conversationError;
if (addCurrentUserError) throw addCurrentUserError;
if (addParticipantError) throw addParticipantError;
redirect(`/messages/${conversationId}`);
};9 Replies
European anchovyOP
Client:
const [isChatCreationInProgress, setIsChatCreationInProgress] =
useState(false);
const createNewChatServer = async (participantId: Profile["id"]) => {
if (isChatCreationInProgress) return;
try {
await createNewChat(participantId);
} catch (error) {
console.log(error);
}
};
const chatFunction = (participantId: Profile["id"]) => {
setIsChatCreationInProgress(true);
if (!usersConversationDictionary[participantId]) {
createNewChatServer(participantId);
}
};European anchovyOP
I've even tried using lodash throttle to limit the amount of clicks...still not working...why ?
You can disable forms after submissions with
https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#displaying-loading-state
useFormStatus() - this way you can prevent the user from hitting it twicehttps://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#displaying-loading-state
European anchovyOP
yes @Marchy , I've done something with useState or different approaches before to prevent the user from spam submitting messages and posts. But the issue is that this is not a form
It's just a div that the user clicks on...
I've also tried to change it into a button instead of a div but it's still not working
European anchovyOP
I've tried to investigate how in god's name this function gets called multiple times and I don't get it...I am doing a console log in my client and in the client it's called ONCE. but in the server it's called 2 times. HOW?
European anchovyOP
I'VE FIXED IT OMG
I removed the server function and instead I am just using it in the client. Because I just want to actually insert data into my database and I am not using a form. However I would still be curious to understand why my approach did not work, because it makes no sense how the client blocks multiple calls to that function but it still gets called 2 times in the server. Is it because of async await ? OR at least I would like to know if I was wrong to use a server action in the first place for this and I should only use server actions IF I am actually using a form and not for inserting data into the database.