Supabase Realtime instellen
Supabase Realtime zendt databasewijzigingen (INSERT, UPDATE, DELETE) uit naar geabonneerde clients via een WebSocket-verbinding. Om het te activeren:
1. Ga in je Supabase-dashboard naar Database → Replication 2. Schakel replicatie in voor de tabellen die je wilt volgen (bijv. metrics, events, orders) 3. Stel RLS-policies in op die tabellen, Supabase Realtime respecteert RLS, dus gebruikers ontvangen alleen wijzigingen voor rijen die ze mogen zien
Dit kost 2 minuten. Het echte werk zit in de frontend: de stroom van wijzigingen verwerken en de UI bijwerken.
WeWeb verbinden met Supabase Realtime
WeWeb's Supabase-plugin ondersteunt realtime-subscriptions native. In WeWeb:
1. Ga naar Plugins → Supabase → je databron 2. Schakel "Realtime" in op de collection die je wilt volgen 3. WeWeb abonneert zich automatisch op wijzigingen en werkt gebonden elementen bij zodra er een wijziging binnenkomt
Voor een metrics-dashboard gebonden aan een metrics-tabel: voeg een Collection toe die gebonden is aan de tabel, schakel Realtime in, en bind grafiek-/getalelementen aan de collection. Wanneer een nieuwe metric-rij wordt ingevoegd in Supabase, werkt het dashboard bij binnen 500ms zonder enige actie van de gebruiker. Hulp nodig hierbij? Onze WeWeb-ontwikkelaars zijn gespecialiseerd in realtime dashboards met WeWeb + Supabase.
De dashboardlayout bouwen
Een typisch realtime dashboard heeft drie zones:
KPI-rij: 3-4 grote getalkaarten bovenaan. Elk gebonden aan een aggregaat (SUM, COUNT, AVG) uit een Supabase-view. Maak in WeWeb een view in Supabase die aggregaten vooraf berekent en bind de KPI-kaarten aan de realtime-collection van die view.
Grafieken: lijndiagram voor tijdreeksdata, staafdiagram voor vergelijkingen, taartdiagram voor verdeling. WeWeb heeft een ingebouwd Chart-component aangedreven door Chart.js. Bind de data-prop aan een Supabase-collection gesorteerd op created_at.
Datatabel: een sorteerbare, filterbare tabel voor de ruwe events. WeWeb's DataGrid-component met zoeken, sorteren en paginering. Schakel Realtime in zodat nieuwe rijen bovenaan verschijnen zodra ze binnenkomen.
Filteren op tijdsbereik
Elk dashboard heeft bediening voor tijdsbereik nodig. Patroon:
1. Voeg een Filter Bar-component toe met preset-knoppen: Laatste 24u, Laatste 7d, Laatste 30d, Aangepast bereik
2. Maak een paginavariabele dateRange met start- en eindtijdstempels
3. Geef dateRange door als filter aan elke Supabase-collection: .gte("created_at", dateRange.start).lte("created_at", dateRange.end)
4. Wanneer de gebruiker een ander bereik selecteert, werk je dateRange bij, alle collections halen automatisch nieuwe data op
Gebruik voor aangepaste datumbereiken WeWeb's Date Picker-component en bind beide invoervelden aan dateRange.start en dateRange.end.
Row-Level Security voor multi-tenant dashboards
Voor SaaS-dashboards waarbij elke klant alleen zijn eigen data ziet:
```sql
-- RLS-policy voor de metrics-tabel
CREATE POLICY "Users see own org metrics"
ON metrics FOR SELECT
USING (
org_id IN (
SELECT org_id FROM memberships
WHERE user_id = auth.uid()
)
);
```
Dit beleid betekent dat dezelfde dashboard-URL voor alle klanten werkt, elk ziet alleen de data van zijn eigen organisatie. Geen filtering nodig in WeWeb. Supabase handhaaft dit op databaseniveau.
Cruciaal: test dit door in te loggen als gebruikers van twee verschillende organisaties en te bevestigen dat de data geïsoleerd is. Een RLS-bug in een dashboard is een ernstig datalek.
Prestatie-optimalisatie voor grote datasets
Dashboards met miljoenen rijen worden snel traag als je aggregaten uitvoert op ruwe data.
Maak Supabase-views voor aggregaten: CREATE MATERIALIZED VIEW daily_metrics AS SELECT DATE(created_at), COUNT(*), SUM(value) FROM events GROUP BY DATE(created_at). Vernieuw de materialized view elk uur via een Supabase Edge Function cron-job.
Gebruik indexen: voeg een index toe op (org_id, created_at) voor elke tabel die gefilterd wordt op organisatie en tijd. Dit verandert een query van 5 seconden in een query van 50ms.
Pagineer de ruwe tabel: laad nooit alle rijen in het dashboard. Gebruik Supabase's .range(0, 99) voor de datatabel en laat gebruikers pagineren. Dit houdt de initiële laadtijd snel, ongeacht het totale aantal rijen.
Supabase Realtime subscriptions in de diepte
Supabase Realtime gebruikt PostgreSQL's logische replicatiefunctie om elke wijziging op rijniveau vast te leggen en uit te zenden naar geabonneerde clients via een WebSocket. Onder de motorkap draait Supabase een Realtime-server (open source, beschikbaar op GitHub) die luistert naar het PostgreSQL-replicatielog en wijzigingsevents in real time doorstuurt naar verbonden clients.
Er zijn twee typen Realtime-kanalen in Supabase. Database Changes luistert naar INSERT-, UPDATE- en DELETE-operaties op specifieke tabellen, met optionele filtering op kolomwaarde (bijvoorbeeld alleen wijzigingen waarbij org_id = 'abc123'). Broadcast laat clients willekeurige berichten sturen naar andere clients die op hetzelfde kanaal geabonneerd zijn, nuttig voor samenwerkingsfuncties zoals "gebruiker X bewerkt dit record op dit moment"-indicatoren.
Voor een dashboard gebruik je voornamelijk Database Changes. Abonneer je op de specifieke tabel en het event-type dat ertoe doet: channel.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'orders' }, (payload) => { /* update UI */ }). Het payload-object bevat de nieuwe rijdata, zodat je deze kunt toevoegen aan de bestaande collection zonder de volledige dataset opnieuw op te halen. Dit maakt realtime efficiënt, elke update is een chirurgische toevoeging aan de lokale state, geen volledige re-query.
Realtime optimaliseren voor meerdere gelijktijdige gebruikers
Wanneer een dashboard honderden of duizenden gelijktijdige gebruikers heeft die allemaal op dezelfde tabel geabonneerd zijn, zendt de Supabase Realtime-server de wijziging uit naar elke abonnee. Dit is efficiënt van ontwerp, één databasewijziging triggert één broadcast die uitwaaiert naar alle clients. De client-side afhandeling moet echter efficiënt zijn om UI-jank te voorkomen bij hoge updatefrequentie.
Voor dashboards die tientallen updates per seconde ontvangen (handelsplatforms, logistiekmonitoring, IoT-sensordata) is het batchen van UI-updates essentieel. In plaats van bij elk event opnieuw te renderen, verzamel je events in een buffer en pas je ze elke 250ms in batches toe. Dit houdt de UI soepel terwijl data toch wordt getoond die op zijn hoogst 250ms oud is, meer dan realtime genoeg voor menselijke perceptie.
Filter subscriptions zo nauw mogelijk. Abonneer je niet op alle wijzigingen op de events-tabel, maar alleen op wijzigingen waarbij org_id = currentUser.orgId. Dit vermindert het aantal events dat elke client ontvangt en verlaagt de belasting op de Realtime-server. In WeWeb ondersteunt de Supabase-plugin filterparameters op realtime-subscriptions, stel altijd het org- of gebruikersfilter in om de subscription af te bakenen.
Strategieën voor het verversen van dashboarddata
Niet elk stukje dashboarddata profiteert van realtime-subscriptions. Sommige data verandert zelden (accountinstellingen, gebruikersprofiel), sommige verandert volgens een bekend schema (dagelijkse totalen, wekelijkse rapporten), en sommige verandert continu (live events, actieve sessies). De ververssingsstrategie afstemmen op het datatype levert een beter presterend dashboard op.
Voor continu veranderende data (bestelaantallen, actieve gebruikers, live omzet) zijn Supabase Realtime-subscriptions de juiste keuze. Data wordt bijgewerkt in minder dan 500ms van de database-insert tot de dashboard-update. Voor data die volgens een schema verandert (gisterens totalen, samenvatting van vorige week) volstaat een handmatige refresh of een getimede re-fetch elke 60 seconden, geen realtime-subscription nodig.
Implementeer in WeWeb de getimede re-fetch met een setInterval in een JavaScript-actie bij het laden van de pagina, die ww.collections.refresh('your-collection-name') aanroept op het geconfigureerde interval. Voor een hybride dashboard met zowel live als geplande data handelt realtime de live feeds af, terwijl getimede refreshes de samenvattingskaarten nauwkeurig houden. Deze combinatie is efficiënter dan alles op realtime abonneren, het vermindert het volume aan WebSocket-events en voorkomt onnodige re-renders van stabiele data.
Realtime-fouten sierlijk afhandelen
WebSocket-verbindingen vallen weg. Mobiele gebruikers wisselen van netwerk. Bedrijfsfirewalls blokkeren WebSocket-upgrades. Een productie-realtime-dashboard moet verbindingsonderbrekingen sierlijk afhandelen in plaats van stilzwijgend verouderde data te tonen.
De Realtime JavaScript-client van Supabase heeft ingebouwde herverbindingslogica. Wanneer de WebSocket de verbinding verliest, probeert de client automatisch opnieuw te verbinden met exponential backoff. Tijdens de verbroken periode ontvangt de client echter geen wijzigingen die aan de database zijn aangebracht. Wanneer de herverbinding slaagt, moet je de betreffende collections opnieuw ophalen om gemiste wijzigingen in te halen, een gap fetch.
Implementeer in WeWeb de gap fetch door je te abonneren op de onError- en onClose-events van het Supabase-kanaal met een custom JavaScript-actie. Wanneer een van beide events afgaat, stel je een paginavariabele connectionStatus in op 'reconnecting' en toon je een zichtbare statusindicator op het dashboard. Wanneer het kanaal opnieuw verbindt (onJoin-event), vernieuw je alle realtime-collections en zet je connectionStatus terug naar 'connected'. Dit patroon zorgt ervoor dat gebruikers altijd weten of de data die ze zien live en actueel is.
Case study: financieel dashboard
Een van de meest veeleisende realtime-dashboardimplementaties die we bij App Studio hebben gebouwd, is een financieel operationeel dashboard voor een fintech-startup die betalingen verwerkt in meerdere Europese markten. Het dashboard volgt live transactievolume, goedkeuringspercentages per betaalmethode, fraudesignalen en afwikkelingsstatus, bijgewerkt in real time terwijl transacties worden verwerkt.
De architectuur gebruikt Supabase als het centrale datawarehouse. Een Edge Function ontvangt webhook-payloads van de betalingsverwerker en voegt verwerkte transactierecords toe aan de transactions-tabel. De Realtime-subscription in WeWeb gaat af bij elke insert, en het dashboard werkt de live tellers bij, voegt de nieuwe transactie toe aan de datatabel, en herberekent de goedkeuringspercentage-grafiek, allemaal binnen 600ms nadat de betaling is verwerkt.
Cruciale implementatiedetails die dit op schaal lieten werken: materialized views voor uurlijkse aggregaten (om dure COUNT/SUM-bewerkingen op de volledige transactions-tabel te vermijden), een samengestelde index op (org_id, created_at, status) voor het gangbare querypatroon, en het batchen van UI-updates om pieken van 20-30 transacties per seconde tijdens piekuren aan te kunnen. Het dashboard verwerkt 50.000+ dagelijkse transacties zonder prestatievermindering, draaiend op Supabase's Pro-plan. Dit is dezelfde architectuur die we toepassen op elk data-intensief WeWeb-dashboard dat we bouwen.