Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

I can't delete an entry from table using SvelteKit & Supabase. Row-Level Security

$
0
0

I'm working on the delete functionality for my SvelteKit app with Supabase integration. The issue I'm facing is that I can only delete an entry when RLS (Row Level Security) is disabled. When RLS is enabled, the delete operation fails with no errors.

Current Setup:

  • SvelteKit + Supabase app.
  • There's a policy on the songs table that allows only the owner of the song to delete it. The owner_id column in the songs table is a foreign key that references the id column in the profile table.

Here’s the policy I’ve created:

CREATE POLICY "Allow delete only if owner" ON songsFOR DELETE TO publicUSING (owner_id = auth.uid());

And my +page.svelte:

<script lang="ts">    import Button from '$lib/components/ui/button/button.svelte';    import { Card, CardContent, CardHeader } from '$lib/components/ui/card';    import { Input } from '$lib/components/ui/input';    import Label from '$lib/components/ui/label/label.svelte';    import { supabase } from '$lib/supabaseClient';    import { toast } from 'svelte-sonner';    import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';    const { data: propsData } = $props();    const { session } = propsData;    console.log(session?.user);    let title = $state('');    let artist = $state('');    let album = $state('');    let year = $state('');    let tags = $state('');    let url = $state('');    let toastState = $state(false);    const handleSubmit = async (event: Event) => {        event.preventDefault();        if (            title.trim() === '' ||            artist.trim() === '' ||            album.trim() === '' ||            year.trim() === '' ||            tags.trim() === '' ||            url.trim() === ''        ) {            toast.error('A field was left empty.');            return null;        }        const songData = {            title,            artist,            album,            year,            tags: tags.split(',').map((tag) => tag.trim()),            url,            owner_id: session?.user.id        };        try {            const response = await fetch('/add', {                method: 'POST',                headers: {'Content-Type': 'application/json'                },                body: JSON.stringify(songData)            });            const result = await response.json();            if (result.success) {                toastState = true;                toast.success('Song added successfully!');                title = '';                artist = '';                album = '';                year = '';                tags = '';                url = '';            } else {                toast('Failed to add song.');            }        } catch (error) {            console.error(error);            toast('An error occurred while adding the song.');        }    };    $effect(() => {        if (toastState) {            setTimeout(() => {                toastState = false;            }, 1000);        }    });    let songs: {        id: string;        title: string;        artist: string;        album: string;        year: string;        tags: string[];        url: string;    }[] = $state([]);    const fetchSongs = async () => {        const { data } = await supabase.from('songs').select('*');        songs = data ?? [];    };    const updateAndFetchSongs = async () => {        supabase            .channel('public:songs')            .on('postgres_changes',                { event: 'INSERT', schema: 'public', table: 'songs' },                (payload: any) => {                    console.log('New song inserted:', payload);                    fetchSongs();                }            )            .on('postgres_changes',                { event: 'UPDATE', schema: 'public', table: 'songs' },                (payload: any) => {                    console.log('Song updated:', payload);                    fetchSongs();                }            )            .on('postgres_changes',                { event: 'DELETE', schema: 'public', table: 'songs' },                (payload: any) => {                    console.log('Song deleted:', payload);                    fetchSongs();                }            )            .subscribe();        await fetchSongs();    };    const deleteSong = async (id: string) => {        console.log('Attempting delete with:', {            songId: id,            userId: session?.user?.id        });        if (!session?.user?.id) {            toast.error('You must be logged in to delete songs');            return;        }        const { error } = await supabase            .from('songs')            .delete()            .eq('id', id)            .eq('owner_id', session.user.id);        if (error) {            console.error('Error deleting song:', error);            toast.error('Failed to delete song');        } else {            toast.success('Song deleted successfully');            await fetchSongs();        }    };    updateAndFetchSongs();</script>

The delete button correctly logs both the song ID and the user ID when clicked as well as my toast saying Song deleted successfully. The Delete button HTML is as so:

<button onclick={() => deleteSong(song.id)}>Delete</button>

Any help is appreciated!


Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>