Backend och databas · 7 min läsning · Uppdaterad 22 augusti 2026
Så lagrar du data i en AI-byggd app med Supabase
Appar byggda i NorthernGo behöver ingen databaskoppling — varje genererad app har redan en Supabase-databas i PostgreSQL inkopplad via ett globalt objekt som heter `window.NorthernGoDB`. Du sparar en post med `await window.NorthernGoDB.save(kollektion, data)` och läser tillbaka den med `await window.NorthernGoDB.get(kollektion)`. Det finns inget schema att definiera och ingen anslutningssträng att klistra in.
Databasen finns redan där
Det vanligaste missförståndet om AI-appbyggare är att du måste ta med dig en egen backend. I NorthernGo behöver du inte det. Varje app som genereras får en databasbrygga injicerad i sig innan du ens ser koden, kopplad till en delad Supabase-instans i PostgreSQL som ligger inom EU.
Bryggan exponeras som ett enda globalt objekt, window.NorthernGoDB. AI-agenterna som skriver din app känner redan till det och använder det som standard, vilket betyder att om du helt enkelt ber om "en att göra-lista som kommer ihåg vad jag skrivit" så sparar den genererade appen redan datan korrekt. Du behöver bara förstå API:t om du vill ändra i koden själv, eller om du vill veta vad som faktiskt händer under ytan.
Det finns ingen tabell att skapa i förväg. Kollektioner skapas första gången du sparar något i dem, och det är medvetet — schemamigrering är precis den sortens arbete som får den som inte är utvecklare att aldrig bli klar med sitt projekt.
Steg 1: Spara din första post
save() tar ett kollektionsnamn och ett vanligt objekt. Objektet får ha vilken form du vill, och kollektionen behöver inte finnas sedan tidigare.
await window.NorthernGoDB.save('uppgifter', {
text: 'Handla mjölk',
klar: false,
skapad: new Date().toISOString()
});
Anropet returnerar ett promise, så det hör hemma i en async-funktion och bör omslutas av try/catch. En misslyckad skrivning utan felhantering är den absolut vanligaste orsaken till att en genererad app verkar "tappa" data — posten kom aldrig fram och ingenting sa till.
async function laggTillUppgift(text) {
try {
await window.NorthernGoDB.save('uppgifter', { text, klar: false });
await renderaUppgifter();
} catch (err) {
console.error(err);
visaMeddelande('Kunde inte spara. Kontrollera uppkopplingen och försök igen.');
}
}
Steg 2: Läs tillbaka datan
get() tar ett kollektionsnamn och returnerar en array med posterna i den. Anropa den en gång när sidan laddas och sedan igen efter varje skrivning, så att gränssnittet alltid speglar vad som faktiskt är lagrat.
window.addEventListener('DOMContentLoaded', async () => {
try {
const uppgifter = await window.NorthernGoDB.get('uppgifter');
renderaUppgifter(uppgifter || []);
} catch (err) {
console.error(err);
renderaUppgifter([]);
}
});
Notera reservvärdet || []. En tom kollektion kan returnera något annat än en array, och renderingskod som utgår från att det är en array kastar fel i en helt ny app utan data. Det här är det näst vanligaste felet i genererade appar, och det ger det värsta symtomet: en helt vit skärm vid första besöket.
Steg 3: Radera poster
delete() tar kollektionen plus ett fältnamn och värdet som ska matchas, i stället för ett internt rad-id. Det gör den användbar från vanlig appkod, där du i regel känner till saken du vill ta bort men inte dess databasnyckel.
await window.NorthernGoDB.delete('uppgifter', 'text', 'Handla mjölk');
Matchar flera poster på fältet och värdet tas alla bort — så matcha på något genuint unikt när det spelar roll. Att spara en egen identifierare vid skrivning är det pålitliga tillvägagångssättet:
const id = crypto.randomUUID();
await window.NorthernGoDB.save('uppgifter', { id, text, klar: false });
await window.NorthernGoDB.delete('uppgifter', 'id', id);
Steg 4: Ge varje användare sin egen data
Allt ovan lagrar data på appnivå: varje besökare ser samma poster. Så snart du vill att människor ska ha privat data behöver appen inloggning, och samma objekt hanterar även det.
await window.NorthernGoDB.register(epost, losenord);
await window.NorthernGoDB.login(epost, losenord);
const arInloggad = !!window.NorthernGoDB.getToken();
window.NorthernGoDB.logout();
Autentiseringen sker medvetet med e-post och lösenord. När en användare är inloggad stämplar plattformen varje skyddad skrivning med hens identitet, och get() returnerar bara hens rader. Du skriver inte filtret själv, och du ska inte sätta fältet _ngOwner — servern skriver över det. Det vanliga mönstret är att kontrollera getToken() vid start och visa antingen inloggningsformuläret eller själva appen.
Delade kollektioner mellan inloggade (ett team-CRM, en intern tavla) hoppar över isoleringen med { shared: true }. Publika kataloger, menyer och highscore-listor använder false så att gäster kan läsa utan konto:
await window.NorthernGoDB.save('kontakter', kontakt, { shared: true });
const allaKontakter = await window.NorthernGoDB.get('kontakter', { shared: true });
await window.NorthernGoDB.save('produkter', produkt, false);
const katalogen = await window.NorthernGoDB.get('produkter', false);
En app-admin (role: 'admin') ser alla rader i appen. Det är kontot som skapas med setupAdmin.
En sak är inte valfri: en app med inloggning måste också ha ett synligt sätt att radera kontot. Det är GDPR artikel 17, inte en trevlig extrafunktion, och SDK:n ger dig ett enda anrop för det.
if (confirm('Detta raderar ditt konto och all din data permanent. Fortsätta?')) {
await window.NorthernGoDB.deleteAccount();
location.reload();
}
Bygg inte en egen raderingsrutt med fetch och försök inte rensa användaren genom att anropa delete() i en loop. deleteAccount() tar bort autentiseringsposten och den tillhörande datan tillsammans; en hemsnickrad variant lämnar med säkerhet något kvar.
Spegla datan till ett system du styr själv
Det finns en separat funktion i arbetsytan som heter Egen Databas, och det är värt att vara exakt med vad den gör, eftersom namnet antyder något den inte är.
Den byter inte ut den inbyggda Supabase-databasen mot en egen, och den tar inte emot en Supabase-anslutningssträng. Den tar en HTTP-endpoint. När den är satt skickas varje skrivning dina appar gör även som en POST till den URL:en, i JSON:
{
"projectId": "abc123",
"collection": "uppgifter",
"data": { "text": "Handla mjölk", "klar": false },
"timestamp": "2026-08-15T09:12:44.000Z"
}
Det gör den till en spegling, inte en ersättning. Den är genuint användbar för att mata in appdata i ditt eget datalager, ett scenario i Zapier eller Make, ett internt CRM eller en Fortnox-integration — men appen fortsätter läsa från den inbyggda databasen oavsett. Behöver du en helt fristående backend är det ärliga svaret att exportera källkoden och peka om den själv.
Vad det här inte ger dig
Att vara tydlig med gränserna sparar mer tid än någon funktionslista.
- Ingen SQL. Du kan inte skriva joins, aggregeringar eller vyer mot kollektionerna från appkoden. API:t är medvetet fyra metoder brett.
- Inga realtidsprenumerationer. Det finns ingen lyssnare som utlöses när en annan användare skriver. Behöver du liveuppdateringar får du polla med ett intervall.
- Köade offlineskrivningar, senast kända läsningar. På en publicerad PWA köas
save()/delete()utan nät i SDK:n och spelas upp när appen är online.get()returnerar senast lyckade lista plus väntande rader. Inloggning, betalning, e-post och AI misslyckas fortfarande utan uppkoppling. Se guiden om offline först. - Ingen schemakontroll. Ingenting hindrar dig från att spara
{ text: 'x' }i en post och{ titel: 'x' }i nästa. Konsekvensen är ditt ansvar.
Felsökning
Datan sparas men försvinner vid omladdning. Nästan alltid skriver appen till localStorage i stället för till databasen. Sök i den genererade koden efter localStorage.setItem — hamnar appdata där finns den bara på en enhet och försvinner när cachen rensas. Be AI:n flytta lagringen till window.NorthernGoDB.
Vit skärm vid första laddningen. Renderingsfunktionen fick något annat än en array från en tom kollektion. Lägg till reservvärdet || [] och omslut inläsningen med try/catch.
Skrivningar gör tyst ingenting. Kontrollera att anropet är awaitat. window.NorthernGoDB.save(...) utan await i en async-funktion hinner ofta bli klar först efter att sidan redan navigerat eller renderats om.
Alla användare ser allas data. Det är förväntat utan inloggning, och för kollektioner som sparas med false (publikt) eller { shared: true } (gemensam inloggad data). Privata poster bakom inloggning isoleras automatiskt; ser två kunder fortfarande varandra skickar den genererade koden false eller shared: true på den kollektionen.
Vanliga frågor
Behöver jag ett eget Supabase-konto för att bygga en app med databas?
Nej. Varje app som genereras i NorthernGo är redan kopplad till en Supabase-databas i PostgreSQL som ligger inom EU, via objektet window.NorthernGoDB. Det finns inget konto att skapa, ingen anslutningssträng att klistra in och ingen tabell att definiera i förväg.
Kan jag koppla in min egen externa databas i stället?
Inte som en ersättning. Inställningen Egen Databas tar en HTTP-endpoint och speglar varje skrivning dit som JSON, så datan når ditt eget system, men appen fortsätter läsa från den inbyggda databasen. För att köra helt på egen backend exporterar du källkoden och pekar om den själv.
Varför tappar min app datan när jag laddar om sidan?
Nästan alltid för att appen skriver till localStorage i stället för till databasen. Data i localStorage finns bara i den enskilda webbläsaren på den enskilda enheten och försvinner när cachen rensas. Sök i koden efter localStorage.setItem och flytta all appdata till window.NorthernGoDB.save.
Kan två användare se varandras data?
Utan inloggning, ja — poster lagras på appnivå och alla ser samma kollektion. Lägger du till register och login via window.NorthernGoDB stämplas varje skyddad skrivning till den användaren, så att samma get-anrop bara returnerar hens egen data. Skicka { shared: true } för team-kollektioner, eller false för en publik katalog.
Fungerar databasen när appen är offline?
På en publicerad PWA, ja för data: get() visar senast synkad lista plus köade sparningar, och save/delete spelas upp när appen är online igen. Inloggning, betalning, e-post och AI i appen kräver fortfarande uppkoppling. Väntande rader märks _pending: true.
Bygg det själv
NorthernGo förvandlar en beskrivning i ren text till en fungerande webbapp med databas, inloggning och en live-adress. Lokal AI-generering körs på ditt eget grafikkort, är obegränsad och ingår gratis i alla prisplaner.