[{"data":1,"prerenderedAt":1237},["ShallowReactive",2],{"blog-de-supabase-schema-cache-column-error":3,"blog-index-de":709},{"id":4,"title":5,"body":6,"category":667,"cover":668,"coverAlt":669,"description":670,"draft":671,"extension":672,"faq":673,"image":688,"keywords":689,"meta":698,"navigation":699,"ogTitle":5,"path":700,"published":701,"seo":702,"stem":703,"tldr":704,"updated":701,"__hash__":708},"blog_de\u002Fblog\u002Fsupabase-schema-cache-column-error.md","Supabase PGRST204: \"Could not find the column in the schema cache\"",{"type":7,"value":8,"toc":653},"minimark",[9,13,24,31,39,44,47,50,73,115,118,124,128,141,150,159,227,239,242,250,257,266,275,279,282,285,291,313,316,340,360,365,369,377,386,402,406,427,440,445,449,452,458,473,476,482,485,489,492,500,503,515,519,522,530,536,550,554,557,564,584,593,611,615,646],[10,11,12],"p",{},"Du hast deinen Builder gebeten, dem Profilformular eine Telefonnummer\nhinzuzufügen. Die Spalte ist im Table Editor zu sehen. Du drückst auf Speichern,\nnichts passiert, und die Browserkonsole zeigt das hier:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","{\n  \"code\": \"PGRST204\",\n  \"details\": null,\n  \"hint\": null,\n  \"message\": \"Could not find the 'phoneNumber' column of 'profiles' in the schema cache\"\n}\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,30],{},"Supabase \"Could not find the column in the schema cache\" heißt, dass deine App\nein Feld speichern wollte, das die Tabelle, so wie PostgREST sie sieht, nicht hat.\nPostgREST ist der Teil von Supabase, der die Aufrufe ",[21,28,29],{},"supabase.from(...)"," deiner\nApp in Datenbankabfragen übersetzt. Es führt eine eigene Liste aller Tabellen und\nSpalten, den Schema-Cache, damit es die Datenbank nicht bei jeder Anfrage nach\nihrem Aufbau fragen muss.",[10,32,33,34,38],{},"Hier liegt der Teil, den die meisten Antworten falsch machen: ",[35,36,37],"strong",{},"Sie sagen dir, du\nsollst den Schema-Cache neu laden."," Bei Supabase lädt sich der Cache jedes Mal\nselbst neu, wenn sich eine Tabelle ändert. Wenn du also gerade eine Spalte\nangelegt hast und diesen Fehler trotzdem siehst, ist der Cache der\nunwahrscheinlichste Grund. Meistens ist es der Name.",[40,41,43],"h2",{"id":42},"was-bedeutet-could-not-find-the-column-in-the-schema-cache","Was bedeutet \"Could not find the column in the schema cache\"?",[10,45,46],{},"Ein Schlüssel in einem Schreibvorgang deiner App hat keine passende Spalte in\ndieser Tabelle.",[10,48,49],{},"Stell dir den Schema-Cache als Hinweistafel im Foyer eines Gebäudes vor: eine\nZeile für jedes Büro, also jede Tabelle, und darunter jeder Raum, also jede\nSpalte. Jede Anfrage deiner App ist ein Lieferschein. PostgREST liest jede Zeile\ndes Lieferscheins gegen die Tafel, und ein Raum, den die Tafel nicht führt, wird\nschon am Empfang abgewiesen, bevor irgendetwas deine Daten erreicht.",[10,51,52,53,56,57,60,61,64,65,72],{},"Die Meldung nennt beide Seiten dieses Vergleichs. In ",[21,54,55],{},"Could not find the 'phoneNumber' column of 'profiles' in the schema cache"," ist ",[21,58,59],{},"phoneNumber"," das,\nwas deine App geschickt hat, und ",[21,62,63],{},"profiles"," die Tabelle, an die es ging. Drei\nweitere Dinge stehen fest im\n",[66,67,71],"a",{"href":68,"rel":69},"https:\u002F\u002Fgithub.com\u002FPostgREST\u002Fpostgrest\u002Fblob\u002Fmain\u002Fsrc\u002Flibrary\u002FPostgREST\u002FError.hs",[70],"nofollow","eigenen Code von PostgREST",":",[74,75,76,84,99],"ul",{},[77,78,79,80,83],"li",{},"der Code ist ",[21,81,82],{},"PGRST204"," und der Status HTTP 400, die Anfrage selbst war also\nfalsch",[77,85,86,87,90,91,94,95,98],{},"er kommt nur von Schreibvorgängen: ",[21,88,89],{},".insert()",", ",[21,92,93],{},".update()"," und ",[21,96,97],{},".upsert()",".\nEin Lesevorgang, der eine fehlende Spalte nennt, scheitert mit einem anderen\nFehler, den Postgres selbst schreibt",[77,100,101,102,106,107,110,111,114],{},"er bringt keinen Hinweis mit. Bei einer\n",[66,103,105],{"href":104},"\u002Fblog\u002Fsupabase-relation-does-not-exist","fehlenden Tabelle"," schlägt PostgREST\nden nächstliegenden Namen vor, den es kennt; bei einer fehlenden Spalte ist ",[21,108,109],{},"hint","\ngleich ",[21,112,113],{},"null",", und den Vergleich machst du",[10,116,117],{},"Jeder Schlüssel im Objekt, das du einem dieser drei Aufrufe übergibst, muss eine\nSpalte dieser Tabelle sein, so geschrieben, wie die Tabelle sie schreibt.",[119,120],"diagram",{"alt":121,"caption":122,"src":123},"Ein Lieferschein mit drei Zeilen neben der Tafel profiles, die vier Räume führt. Zwei Zeilen des Lieferscheins führen zu Räumen mit demselben Namen und sind abgehakt. Die dritte Zeile, phoneNumber, endet bernsteinfarben an einem Ungleich-Zeichen neben phone_number.","PostgREST vergleicht jeden Schlüssel, den deine App schickt, Buchstabe für Buchstabe mit den Spalten auf seiner Liste. phoneNumber und phone_number sind zwei verschiedene Namen.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fletter-for-letter-1600x700.png",[40,125,127],{"id":126},"ursache-1-der-name-passt-nicht-buchstabe-für-buchstabe","Ursache 1: Der Name passt nicht, Buchstabe für Buchstabe",[10,129,130,131,90,133,136,137,140],{},"Die Prüfung ist exakt. Für PostgREST sind ",[21,132,59],{},[21,134,135],{},"phone_number"," und\n",[21,138,139],{},"phonenumber"," drei verschiedene Spalten, und deine Tabelle hat höchstens eine\ndavon.",[10,142,143,144,146,147,149],{},"Es gibt zwei übliche Wege hierher. Der erste sind zwei Benennungsgewohnheiten,\ndie aufeinandertreffen: JavaScript schreibt ein Feld meist als ",[21,145,59],{},", eine\nPostgres-Spalte heißt meist ",[21,148,135],{},". Der Code, den dein Builder geschrieben\nhat, und das SQL, das er ausgeführt hat, können jeweils für sich stimmen und sich\ntrotzdem widersprechen.",[10,151,152,153,158],{},"Der zweite ist die Falle mit den Anführungszeichen. In SQL wird ein Name ohne\ndoppelte Anführungszeichen in Kleinbuchstaben umgewandelt. Die\n",[66,154,157],{"href":155,"rel":156},"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fsql-syntax-lexical.html",[70],"Dokumentation von Postgres","\nsagt es klar: \"Quoting an identifier also makes it case-sensitive, whereas\nunquoted names are always folded to lower case.\"",[160,161,162,178],"table",{},[163,164,165],"thead",{},[166,167,168,172,175],"tr",{},[169,170,171],"th",{},"Was du im SQL Editor ausgeführt hast",[169,173,174],{},"Die Spalte, die entstand",[169,176,177],{},"Was deine App schicken muss",[179,180,181,197,212],"tbody",{},[166,182,183,189,193],{},[184,185,186],"td",{},[21,187,188],{},"alter table profiles add column phone_number text;",[184,190,191],{},[21,192,135],{},[184,194,195],{},[21,196,135],{},[166,198,199,204,208],{},[184,200,201],{},[21,202,203],{},"alter table profiles add column phoneNumber text;",[184,205,206],{},[21,207,139],{},[184,209,210],{},[21,211,139],{},[166,213,214,219,223],{},[184,215,216],{},[21,217,218],{},"alter table profiles add column \"phoneNumber\" text;",[184,220,221],{},[21,222,59],{},[184,224,225],{},[21,226,59],{},[10,228,229,230,232,233,235,236,238],{},"Die mittlere Zeile ist die, an der Leute hängen bleiben. Das SQL sieht aus, als\nhätte es ",[21,231,59],{}," angelegt, der Code schickt ",[21,234,59],{},", und die Spalte\nheißt ",[21,237,139],{},".",[10,240,241],{},"Um die echten Namen zu sehen, öffne die Tabelle im Table Editor und lies die\nSpaltenköpfe, oder führ das hier im SQL Editor aus:",[14,243,248],{"className":244,"code":246,"language":247,"meta":23},[245],"language-sql","select column_name\nfrom information_schema.columns\nwhere table_schema = 'public' and table_name = 'profiles';\n","sql",[21,249,246],{"__ignoreMap":23},[10,251,252,253,256],{},"Dann sieh dir an, was deine App geschickt hat. Öffne in den Entwicklertools\ndeines Browsers den Tab Netzwerk (Network), klick die fehlgeschlagene Anfrage an\n",[21,254,255],{},"\u002Frest\u002Fv1\u002Fprofiles"," an und lies ihren Payload.",[10,258,259,260,262,263,265],{},"Die sicherere Lösung ist, die App zu ändern, weil das nichts an deinen Daten\nberührt. Bitte deinen Builder, überall dort, wo dieses Feld gespeichert wird, den\nexakten Namen der Spalte zu verwenden: \"die Spalte in ",[21,261,63],{}," heißt\n",[21,264,135],{},"; nutze diesen Namen in jedem Insert und Update\". Die Spalte\nstattdessen umzubenennen ist eine Änderung an einer Tabelle im laufenden Betrieb,\nund jeder andere Bildschirm, der noch den alten Namen nutzt, bricht beim ersten\nAufruf.",[10,267,268,269,274],{},"Wenn du mit Lovable baust, geh den Chat zurück und such nach einer\nDatenbankänderung, die du freigeben solltest. Lovables\n",[66,270,273],{"href":271,"rel":272},"https:\u002F\u002Fdocs.lovable.dev\u002Fintegrations\u002Fsupabase",[70],"Supabase-Dokumentation"," sagt, es\n\"writes the SQL, shows it to you, and asks for your approval in the project chat\nbefore running it\". Bis du sie freigibst, gibt es die Spalte nicht, egal was der\nCode erwartet.",[40,276,278],{"id":277},"ursache-2-ein-schlüssel-der-nie-eine-spalte-war","Ursache 2: Ein Schlüssel, der nie eine Spalte war",[10,280,281],{},"Die Anfrage trägt etwas, das die Tabelle nie speichern sollte: verknüpfte Zeilen,\ndie im Insert verschachtelt sind, oder ein Feld, das das Formular für sich selbst\nbraucht.",[10,283,284],{},"Beim verschachtelten Insert erwarten die Leute, dass er funktioniert:",[14,286,289],{"className":287,"code":288,"language":19},[17],"await supabase.from('orders').insert({\n  customer_id: user.id,\n  total: 42,\n  order_items: [{ product_id: 7, quantity: 2 }],\n})\n",[21,290,288],{"__ignoreMap":23},[10,292,293,294,297,298,301,302,307,308,238],{},"Das scheitert mit ",[21,295,296],{},"Could not find the 'order_items' column of 'orders' in the schema cache",". Dieselbe Form zu lesen funktioniert:\n",[21,299,300],{},".select('*, order_items(*)')"," liefert eine Bestellung samt ihren Positionen, also\nsieht es so aus, als müsste auch der umgekehrte Weg gehen. PostgREST liest jeden\nSchlüssel eines Schreibvorgangs als Spalte der einen Tabelle, für die die Anfrage\ngilt. Ein Supabase-Nutzer\n",[66,303,306],{"href":304,"rel":305},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase\u002Fissues\u002F50816",[70],"meldete es als Bug",", und die\nAntwort, bevor das Issue am 18. Oktober 2026 geschlossen wurde, lautete, dass\nverschachtelte Inserts eine fehlende Funktion sind. Der Wunsch danach steht seit\nFebruar 2017 offen im\n",[66,309,312],{"href":310,"rel":311},"https:\u002F\u002Fgithub.com\u002FPostgREST\u002Fpostgrest\u002Fissues\u002F818",[70],"Tracker von PostgREST",[10,314,315],{},"Zwei weitere Formen desselben Problems:",[74,317,318,331],{},[77,319,320,321,323,324,327,328,330],{},"eine Zeile, die zusammen mit ihren verknüpften Zeilen gelesen, in einem\nFormular bearbeitet und als Ganzes per ",[21,322,93],{}," zurückgeschickt wird, sodass\ndas angehängte ",[21,325,326],{},"order_items"," oder ",[21,329,63],{}," mitgeht",[77,332,333,334,336,337],{},"der gesamte Zustand eines Formulars, direkt an ",[21,335,89],{}," übergeben, mit\nFeldern, die das Formular braucht und die Tabelle nicht, etwa ",[21,338,339],{},"confirmPassword",[10,341,342,343,346,347,350,351,354,355,359],{},"Die Lösung: Schreib jede Tabelle für sich, die Elterntabelle zuerst. Leg die\nBestellung an, lass dir ihre id mit ",[21,344,345],{},".select('id').single()"," zurückgeben und leg\ndann die Positionen mit dieser ",[21,348,349],{},"order_id"," an. Das sind zwei Anfragen, wenn also\ndie zweite scheitert, ist die Bestellung trotzdem ohne ihre Positionen\ngespeichert. Wenn das nie passieren darf, pack beide Inserts in eine\nPostgres-Funktion und ruf sie mit ",[21,352,353],{},".rpc()"," auf, was die Antwort in jenem Issue\ndas übliche Muster nennt. Dann wird alles gespeichert oder nichts. Antwortet\ndieser Aufruf stattdessen mit PGRST202, erklärt\n",[66,356,358],{"href":357},"\u002Fblog\u002Fsupabase-function-not-found","die Funktionsversion dieses Fehlers",", warum.",[119,361],{"alt":362,"caption":363,"src":364},"Obere Bahn: Ein Lieferschein mit einem zweiten Lieferschein darin geht an die Tafel orders. Seine zwei einfachen Zeilen sind abgehakt, der innere bleibt an einem bernsteinfarbenen Kreuz stehen, verbunden mit einem Schild mit PGRST204 und 400. Untere Bahn: zwei Lieferscheine nacheinander, nummeriert 1 und 2, jeder an seine eigene Tafel, beide abgehakt.","Ein verschachtelter Lieferschein wird als eine weitere Spalte der ersten Tabelle gelesen. Getrennt verschickt, die Elterntabelle zuerst, findet jeder seine eigene Tafel.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fa-key-that-is-not-a-column-1600x720.png",[40,366,368],{"id":367},"ursache-3-die-änderung-ging-in-ein-anderes-projekt","Ursache 3: Die Änderung ging in ein anderes Projekt",[10,370,371,372,376],{},"Die Spalte existiert, in einer Datenbank, mit der deine App nie spricht. Ein\nSupabase-Konto kann mehrere Projekte enthalten, und ein\n",[66,373,375],{"href":374},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branch ist ein eigenes Projekt"," mit\neigener Datenbank. Eine Spalte, die im SQL Editor des falschen angelegt wird,\nändert eine Tafel in einem anderen Gebäude.",[10,378,379,380,385],{},"Im\n",[66,381,384],{"href":382,"rel":383},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase\u002Fissues\u002F42183",[70],"Issue #42183"," von Supabase,\neiner Meldung, der Cache aktualisiere sich nicht (\"does not update\"), egal was\nman versuche, antwortete einer der Entwickler von PostgREST, dass die Meldung\nzwei verschiedene Projektreferenzen nannte, und bat darum zu bestätigen, dass die\nÄnderung in dem Projekt gemacht wurde, an das die Anfragen gingen.",[10,387,388,389,392,393,396,397,401],{},"Die Prüfung braucht zwei Adressen. Deine App ruft\n",[21,390,391],{},"https:\u002F\u002F\u003Creference>.supabase.co"," auf, was du bei jeder Anfrage im Tab Netzwerk\nsiehst. Das Dashboard zeigt das Projekt, in dem du bist, unter\n",[21,394,395],{},"supabase.com\u002Fdashboard\u002Fproject\u002F\u003Creference>",". Die beiden Referenzen müssen\ndieselbe Zeichenkette sein.\n",[66,398,400],{"href":399},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Welches Projekt ist meins"," erklärt, wie\ndu es findest, wenn jemand anderes Supabase eingerichtet hat.",[40,403,405],{"id":404},"ursache-4-der-cache-ist-wirklich-veraltet","Ursache 4: Der Cache ist wirklich veraltet",[10,407,408,409,412,413,416,417,420,421,426],{},"Das ist bei Supabase der seltene Fall, weil Supabase den Cache für dich neu lädt.\nJede Supabase-Datenbank wird mit einem Event-Trigger namens ",[21,410,411],{},"pgrst_ddl_watch","\neingerichtet, der nach jeder Änderung am Aufbau der Datenbank läuft, ",[21,414,415],{},"ALTER TABLE","\neingeschlossen, und ",[21,418,419],{},"NOTIFY pgrst, 'reload schema'"," sendet: die Nachricht, die\nPostgREST sagt, seine Liste neu aufzubauen. Du kannst ihn im\n",[66,422,425],{"href":423,"rel":424},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fpostgres\u002Fblob\u002Fdevelop\u002Fmigrations\u002Fschema-17.sql",[70],"Datenbank-Setup von Supabase","\nnachlesen. Eine Spalte im Table Editor oder im SQL Editor anzulegen, beschriftet\ndie Tafel von selbst neu.",[10,428,429,430,435,436,439],{},"Schief geht es, wenn diese Nachricht nie ankommt. Supabases\n",[66,431,434],{"href":432,"rel":433},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Fpostgrest-not-recognizing-new-columns-or-functions-bd75f5",[70],"Anleitung zur Fehlersuche","\nbeschreibt den Fall: \"an underlying Postgres notification queue issue prevents\nPostgREST from receiving cache reload signals after schema changes\". Das Log von\nPostgREST zeigt dann ",[21,437,438],{},"Failed listening for database notifications on the \"pgrst\" channel",", und die Tafel bleibt, wie sie war, egal wie viele Spalten du anlegst.",[119,441],{"alt":442,"caption":443,"src":444},"Obere Bahn: ALTER TABLE fügt einer Tabelle eine Spalte hinzu, eine Glocke läutet, eine Linie mit NOTIFY pgrst erreicht die Tafel profiles, und die Tafel bekommt dasselbe neue Schild. Untere Bahn: dieselbe Änderung, die Linie von einem bernsteinfarbenen Kreuz unterbrochen, und die Tafel mit einem gestrichelten leeren Platz, wo das neue Schild sein sollte.","Jedes ALTER TABLE bei Supabase sendet die Nachricht zum Neuladen von selbst. Ein veralteter Cache heißt, dass diese Nachricht nicht angekommen ist.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fthe-board-repaints-itself-1600x660.png",[40,446,448],{"id":447},"wie-lade-ich-den-supabase-schema-cache-neu","Wie lade ich den Supabase-Schema-Cache neu?",[10,450,451],{},"Führ eine Zeile im SQL Editor aus:",[14,453,456],{"className":454,"code":455,"language":247,"meta":23},[245],"NOTIFY pgrst, 'reload schema';\n",[21,457,455],{"__ignoreMap":23},[10,459,460,461,466,467,472],{},"Supabases\n",[66,462,465],{"href":463,"rel":464},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Frefresh-postgrest-schema",[70],"Seite dazu","\nsagt, du solltest unter Results \"Success. No rows returned\" sehen. Das ist bei\neiner laufenden App unbedenklich. Die\n",[66,468,471],{"href":469,"rel":470},"https:\u002F\u002Fdocs.postgrest.org\u002Fen\u002Fv14\u002Freferences\u002Fschema_cache.html",[70],"Dokumentation von PostgREST","\nsagt \"Requests will wait until the schema cache reload is done\", also sieht\nniemand, der die App gerade nutzt, währenddessen einen Fehler.",[10,474,475],{},"Ist die Benachrichtigungswarteschlange das Problem, bleibt die Nachricht zum\nNeuladen genauso hängen wie die automatische. Die Anleitung zur Fehlersuche\nnennt dafür eine zweite Zeile:",[14,477,480],{"className":478,"code":479,"language":247,"meta":23},[245],"select pg_notification_queue_usage();\n",[21,481,479],{"__ignoreMap":23},[10,483,484],{},"Laut Supabase bringt sie PostgREST dazu, seinen Cache zu aktualisieren, und \"does\nnot require a database instance or PostgREST service restart\". Dann versuch das\nSpeichern noch einmal.",[40,486,488],{"id":487},"wenn-neuladen-nicht-hilft","Wenn Neuladen nicht hilft",[10,490,491],{},"Starte das Projekt neu, und wenn der Fehler auch das übersteht, geh zurück zu den\nUrsachen 1 bis 3.",[10,493,494,495,499],{},"Ein Neustart gibt PostgREST immer eine frische Liste. Derselbe Entwickler von\nPostgREST schrieb in #42183, dass ein neu gestartetes PostgREST \"won't go live if\nit doesn't load a new schema cache\". Restart project findest du unter Project\nSettings, dann General, und\n",[66,496,498],{"href":497},"\u002Fblog\u002Fis-supabase-down-or-your-app","wie man ein Supabase-Projekt neu startet","\nführt dich durch, samt der paar Minuten, die es offline ist.",[10,501,502],{},"Ein Fehler, der einen Neustart übersteht, kommt also von einer frischen, genauen\nListe: Diese Tabelle in diesem Projekt hat keine Spalte mit diesem Namen. #42183\nselbst, im Januar 2026 von jemandem eröffnet, der Neuladen, Neustart und das\nLöschen und Neuanlegen der Spalte versucht hatte, war noch offen, als wir es am\n21. Oktober 2026 gelesen haben. Die Antwort des Entwicklers dort schlug außerdem\nvor, in den Infrastructure-Einstellungen des Projekts auf PostgREST 14 zu\naktualisieren.",[10,504,505,506,509,510,514],{},"Streich Löschen und Neuanlegen von deiner Liste. ",[21,507,508],{},"alter table … drop column","\nlöscht jeden Wert, der in dieser Spalte gespeichert ist, und die neue Spalte mit\ndemselben Namen beginnt leer. Wenn du gleich eine Tabelle ändern willst, in die\nechte Nutzer schreiben, behalte eine Kopie der Datenbank von vor der Änderung.\n",[66,511,513],{"href":512},"\u002Fsupabase-backups","Reeve Care"," legt eine nach Zeitplan an und bewahrt sie\nverschlüsselt auf Reeves eigenem Speicher in der EU auf.",[40,516,518],{"id":517},"deine-generierten-typen-auf-stand-halten","Deine generierten Typen auf Stand halten",[10,520,521],{},"Generiere deine TypeScript-Typen nach jeder Änderung an einer Tabelle neu, dann\nkann ein falsch geschriebener Spaltenname schon im Editor auffallen, bevor er die\nLive-Seite erreicht.",[10,523,524,525,72],{},"Supabase baut die Datei aus deinen echten Spalten, entweder im Dashboard oder mit\neinem Befehl aus seiner\n",[66,526,529],{"href":527,"rel":528},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fapi\u002Frest\u002Fgenerating-types",[70],"Anleitung zum Generieren von Typen",[14,531,534],{"className":532,"code":533,"language":19},[17],"npx supabase gen types typescript --project-id \"$PROJECT_REF\" --schema public > database.types.ts\n",[21,535,533],{"__ignoreMap":23},[10,537,538,539,542,543,546,547,549],{},"Wird der Client mit diesen Typen erstellt, ",[21,540,541],{},"createClient\u003CDatabase>(…)",", führt der\nTyp ",[21,544,545],{},"Insert"," jeder Tabelle die Spalten auf, die ",[21,548,89],{}," annimmt. Eine falsch\ngeschriebene Spalte in einem Objekt, das direkt im Aufruf ausgeschrieben ist,\nwird dann als Fehler markiert, bevor du veröffentlichst. Laut Lovables\nDokumentation \"regenerates the TypeScript types your app uses\" es nach einer\nDatenbankänderung. Eine Typdatei, die vor deiner letzten Änderung an der Tabelle\ngeneriert wurde, führt noch die alten Spalten.",[40,551,553],{"id":552},"eine-tabelle-im-laufenden-betrieb-ändern-ohne-zu-verlieren-was-drinsteht","Eine Tabelle im laufenden Betrieb ändern, ohne zu verlieren, was drinsteht",[10,555,556],{},"Behalte eine Kopie von vor der Änderung und wisse sofort, ob die App danach noch\nantwortet.",[10,558,559],{},[35,560,561,563],{},[66,562,513],{"href":512}," bewahrt eine Kopie deiner Supabase-Datenbank auf:",[74,565,566,569,572,575,578,581],{},[77,567,568],{},"eine verschlüsselte Kopie nach Zeitplan, auf Reeves eigenem Speicher in der EU, außerhalb deines Supabase-Kontos",[77,570,571],{},"die letzte Kopie vor deiner Änderung enthält die Tabellen und Spalten, wie sie waren, samt Zeilen",[77,573,574],{},"jede Kopie wird geprüft, bevor sie zählt, indem die Zeilen in jeder Tabelle gezählt werden",[77,576,577],{},"auch deine hochgeladenen Dateien, sobald du eine Storage-Zugangsberechtigung verbindest",[77,579,580],{},"Wiederherstellung mit einem Klick, vorher wird eine Sicherheitskopie des aktuellen Stands angelegt",[77,582,583],{},"alles, was Monitor macht",[10,585,586],{},[35,587,588,592],{},[66,589,591],{"href":590},"\u002Fwebsite-monitoring","Reeve Monitor"," prüft weiter von außen:",[74,594,595,598,601,608],{},[77,596,597],{},"ob deine App erreichbar ist, jede Minute geprüft, sodass ein kaputter Speichern-Knopf und ein Ausfall leicht auseinanderzuhalten sind",[77,599,600],{},"der vollständige Sicherheitscheck jede Stunde, für bis zu drei Apps",[77,602,603,604,607],{},"eine Nachricht, wenn sich ein Ergebnis ",[35,605,606],{},"ändert",", sodass ein Deploy, der ändert, was deine App preisgibt, dich erreicht, ohne dass du nachsehen musst",[77,609,610],{},"ein monatlicher Bericht in klarer Sprache über das, was er gesehen hat",[40,612,614],{"id":613},"was-du-jetzt-tun-solltest","Was du jetzt tun solltest",[616,617,618],"key-takeaways",{},[74,619,620,623,626,629,632,643],{},[77,621,622],{},"Lies die zwei Namen in der Meldung: den Schlüssel, den deine App geschickt hat, und die Tabelle, an die er ging.",[77,624,625],{},"Vergleich diesen Schlüssel Buchstabe für Buchstabe mit der Spalte im Table Editor. Ein Name, der in SQL ohne Anführungszeichen geschrieben wurde, wird in Kleinbuchstaben gespeichert.",[77,627,628],{},"Such nach Schlüsseln, die keine Spalten sind: verknüpfte Zeilen, die in einem Insert verschachtelt sind, oder eine ganze Zeile, die mit ihren verknüpften Zeilen zurückgeschickt wird. Schreib jede Tabelle für sich, oder pack beide Schreibvorgänge in eine Funktion.",[77,630,631],{},"Prüf, dass die Referenz in der Supabase-Adresse deiner App zu dem Projekt passt, das du geändert hast.",[77,633,634,635,638,639,642],{},"Passt das alles, führ ",[21,636,637],{},"NOTIFY pgrst, 'reload schema';"," aus, dann ",[21,640,641],{},"select pg_notification_queue_usage();",", und starte das Projekt nur neu, wenn keins von beiden hilft.",[77,644,645],{},"Generiere deine TypeScript-Typen nach jeder Änderung an einer Tabelle neu.",[10,647,648,649,652],{},"Fang mit dem Spaltennamen an, den die Meldung zitiert, denn er ist genau das, was\ndeine App geschickt hat, und der Table Editor zeigt genau das, was die Tabelle\nhat. Bevor du in einer Tabelle, die Leute nutzen, etwas umbenennst oder löschst,\n",[66,650,651],{"href":512},"behalte eine Kopie der Datenbank"," von vor der Änderung.",{"title":23,"searchDepth":654,"depth":654,"links":655},3,[656,658,659,660,661,662,663,664,665,666],{"id":42,"depth":657,"text":43},2,{"id":126,"depth":657,"text":127},{"id":277,"depth":657,"text":278},{"id":367,"depth":657,"text":368},{"id":404,"depth":657,"text":405},{"id":447,"depth":657,"text":448},{"id":487,"depth":657,"text":488},{"id":517,"depth":657,"text":518},{"id":552,"depth":657,"text":553},{"id":613,"depth":657,"text":614},"Sicherheitsgrundlagen","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcover-1200x630.png","Eine Hinweistafel im Foyer mit einem leeren Platz in ihrer Liste der Räume, davor ein Lieferschein mit einer bernsteinfarben markierten Zeile.","Supabase \"Could not find the column in the schema cache\" heißt meist: Der Name passt nicht. Vier Prüfungen und der Einzeiler zum Neuladen.",false,"md",[674,677,680,682,685],{"q":675,"a":676},"Was bedeutet PGRST204?","PGRST204 ist der Code, den PostgREST, der Teil von Supabase, der die Datenbankaufrufe deiner App beantwortet, einem Schreibvorgang gibt, der eine Spalte nennt, die die Tabelle nicht hat. Er kommt mit HTTP 400 und der Meldung \"Could not find the 'x' column of 'y' in the schema cache\" zurück, wobei x der Schlüssel ist, den deine App geschickt hat, und y die Tabelle. Inserts, Updates und Upserts lösen ihn aus.",{"q":678,"a":679},"Ich habe die Spalte angelegt und es schlägt trotzdem fehl. Warum?","Meist liegt es am Namen. Prüf, dass deine App genau den gespeicherten Namen schickt (eine Spalte, die in SQL ohne Anführungszeichen als phoneNumber angelegt wurde, heißt gespeichert phonenumber), dass du sie in dem Projekt angelegt hast, das deine App aufruft, und dass sonst nichts in der Anfrage ein Schlüssel ist, den die Tabelle nicht kennt. Supabase lädt den Schema-Cache nach jedem ALTER TABLE von selbst neu, ein veralteter Cache ist also das Letzte, was du verdächtigen solltest.",{"q":448,"a":681},"Führ NOTIFY pgrst, 'reload schema'; im SQL Editor aus. Ändert das nichts, nennt Supabases Anleitung zur Fehlersuche einen zweiten Befehl, select pg_notification_queue_usage();, für den Fall, dass die Nachrichten zum Neuladen feststecken. Anfragen, die während des Neuladens ankommen, warten, bis es fertig ist.",{"q":683,"a":684},"Leert das Pausieren des Projekts den Cache?","Ja. PostgREST baut bei jedem Start einen frischen Schema-Cache, und ein pausiertes Projekt startet es beim Fortsetzen neu. Restart project unter Project Settings und dann General macht dasselbe ohne Pause. Übersteht der Fehler beides, lag der Cache die ganze Zeit richtig: Die Spalte fehlt in dieser Tabelle in diesem Projekt.",{"q":686,"a":687},"Warum scheitern verschachtelte Inserts mit diesem Fehler?","Weil PostgREST jeden Schlüssel eines Insert als Spalte einer einzigen Tabelle liest, und ein Schlüssel mit verknüpften Zeilen ist eine Spalte, die es nicht findet. Verknüpfte Zeilen in einer Anfrage zu lesen funktioniert, sie so zu schreiben wurde nie unterstützt. Leg zuerst den Elterndatensatz an und dann die Kinder mit seiner id, oder erledige beides in einer Postgres-Funktion, die du mit rpc() aufrufst.","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",[690,691,692,693,694,695,696,697],"could not find the column in the schema cache","pgrst204","supabase could not find the column of in the schema cache","supabase schema cache aktualisiert nicht","notify pgrst reload schema","supabase neue spalte funktioniert nicht","supabase schema cache neu laden","supabase verschachtelter insert",{},true,"\u002Fblog\u002Fsupabase-schema-cache-column-error","2026-10-21",{"title":5,"description":670},"blog\u002Fsupabase-schema-cache-column-error",[705,706,707],"Supabase \"Could not find the column in the schema cache\" (PGRST204) heißt: Deine App wollte ein Feld speichern, das die Tabelle nicht führt. PostgREST prüft jeden Schlüssel eines Insert oder Update gegen seine eigene Kopie deines Schemas, Buchstabe für Buchstabe.","Die übliche Ursache ist der Name: phoneNumber an eine Spalte namens phone_number geschickt, oder ein Schlüssel, der nie eine Spalte war, etwa verknüpfte Zeilen, die in einem Insert verschachtelt sind.","Supabase lädt diese Kopie von selbst neu, sobald sich eine Tabelle ändert. Ist sie wirklich veraltet, lädt NOTIFY pgrst, 'reload schema'; im SQL Editor sie neu, während die App weiterläuft.","QJwtj3MTwbyyDBhRRMqoD-B4gTlZwon_jiaKKiMPhUU",[710,716,722,728,734,740,746,752,758,764,770,777,783,789,795,801,807,813,818,823,824,830,836,842,848,854,860,866,872,878,884,890,896,902,908,914,920,926,932,938,943,949,955,961,967,973,978,984,990,996,1002,1008,1014,1020,1026,1032,1038,1044,1050,1056,1062,1068,1074,1080,1086,1092,1098,1104,1110,1116,1122,1128,1134,1140,1146,1151,1157,1163,1168,1174,1180,1186,1192,1198,1203,1209,1215,1221,1226,1232],{"path":711,"title":712,"description":713,"published":714,"category":667,"image":715,"draft":671},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\" erklärt","Supabase \"max client connections reached\": Der Pooler hat keinen Platz für noch einen Client. Der Port in deinem Connection String setzt das Limit.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":717,"title":718,"description":719,"published":720,"category":667,"image":721,"draft":671},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Supabase-Fehler: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\" heißt: Google-Login ist in deinem Supabase-Projekt aus. Die Lösung, und was bei redirect_uri_mismatch hilft.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":723,"title":724,"description":725,"published":726,"category":667,"image":727,"draft":671},"\u002Fblog\u002Fviolates-foreign-key-constraint","Supabase-Fehler \"violates foreign key constraint\" beim Einfügen","Supabase \"insert or update on table violates foreign key constraint\": Deine Zeile zeigt auf eine, die es nicht gibt. Welche, warum, und die Lösung.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":729,"title":730,"description":731,"published":732,"category":667,"image":733,"draft":671},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Supabase-Fehler \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": Eine Pflichtspalte kam leer an. Woher die Null kommt, und die Lösung.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":735,"title":736,"description":737,"published":738,"category":667,"image":739,"draft":671},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": wo die Sitzung geblieben ist","\"Auth session missing!\" heißt: supabase-js fand keine angemeldete Sitzung und fragte Supabase gar nicht erst. Wo die Sitzung blieb, und die Lösung je Fall.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":741,"title":742,"description":743,"published":744,"category":667,"image":745,"draft":671},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": niemand ist angemeldet","\"invalid claim: missing sub claim\" heißt: Supabase Auth bekam ein echtes Token ohne Nutzer darin, deinen Projektschlüssel statt einer Sitzung.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":747,"title":748,"description":749,"published":750,"category":667,"image":751,"draft":671},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": der echte Grund","\"Failed to send a request to the Edge Function\" heißt: Der Browser hat keine lesbare Antwort bekommen. Seine Konsole sagt, warum, und ob deine Funktion lief.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":753,"title":754,"description":755,"published":756,"category":667,"image":757,"draft":671},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Warum Supabase-E-Mail-Links auf localhost:3000 weiterleiten","Leitet Supabase auf localhost:3000 um, ist die Site URL unverändert, oder deine Adresse fehlt in Redirect URLs. Die Lösung und der Platzhalter, den du meidest.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":759,"title":760,"description":761,"published":762,"category":667,"image":763,"draft":671},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" bei einem neuen Link","Bei einem Link von vor einer Minute heißt Supabases \"Email link is invalid or has expired\" meist: Ein Mailfilter hat ihn zuerst benutzt. Prüfen und beheben.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":765,"title":766,"description":767,"published":768,"category":667,"image":769,"draft":671},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\" erklärt","Supabase \"canceling statement due to statement timeout\": Eine Abfrage lief länger als ihre Rolle darf, 3 Sekunden für Besucher. Prüf zuerst die RLS-Regel.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":771,"title":772,"description":773,"published":774,"category":775,"image":776,"draft":671},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" in Supabase und was mitgelöscht wird","\"Database error deleting user\" in Supabase heißt: Deine Datenbank hat das Löschen abgelehnt. Der Grund steht im Log, die Lösung entscheidet, was mitgeht.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":778,"title":779,"description":780,"published":781,"category":667,"image":782,"draft":671},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" bei Supabase","Ein Stripe-Webhook in einer Supabase Edge Function meldet \"No signatures found matching the expected signature\"? Zwei Ursachen. Prüfe weiter.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":784,"title":785,"description":786,"published":787,"category":667,"image":788,"draft":671},"\u002Fblog\u002Fsupabase-invalid-login","\"Invalid login credentials\" in Supabase: die drei Ursachen","Supabase sagt \"Invalid login credentials\" bei falschem Passwort, unbekannter E-Mail und Google-Konto. So erkennst du, welcher Fall es ist.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":790,"title":791,"description":792,"published":793,"category":667,"image":794,"draft":671},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": der echte Fehler","\"Edge Function returned a non-2xx status code\" heißt: Deine Supabase-Funktion hat mit einem Fehler geantwortet. So liest du den echten.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":796,"title":797,"description":798,"published":799,"category":667,"image":800,"draft":671},"\u002Fblog\u002Fcertificate-not-trusted","Zertifikat nicht vertrauenswürdig: drei Ursachen außer Ablauf","Zertifikat nicht vertrauenswürdig, obwohl das Datum stimmt? Es nennt eine andere Adresse, hat sich selbst signiert oder seiner Kette fehlt ein Glied.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":802,"title":803,"description":804,"published":805,"category":667,"image":806,"draft":671},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": was im Zitat steht","Supabase \"invalid input syntax for type uuid\" heißt: Deine App hat etwas geschickt, das keine ID ist. Zitat lesen, Abfrage zurückhalten, Spalte behalten.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":808,"title":809,"description":810,"published":811,"category":667,"image":812,"draft":671},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\" erklärt","Supabase \"duplicate key value violates unique constraint\" heißt: Der Wert ist schon vergeben. Spalte finden, Lösung wählen, Wert vom Bildschirm fernhalten.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":104,"title":814,"description":815,"published":816,"category":667,"image":817,"draft":671},"Supabase \"relation does not exist\", obwohl die Tabelle da ist","Supabase \"relation does not exist\" oder PGRST205: Keine Tabelle passt zu Name und Schema deiner Abfrage. Vier Prüfungen, und was eine Freigabe öffnet.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":357,"title":819,"description":820,"published":821,"category":667,"image":822,"draft":671},"Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" nennt die Argumente, die deine App geschickt hat. Vergleich sie mit der Funktion.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":700,"title":5,"description":670,"published":701,"category":667,"image":688,"draft":671},{"path":825,"title":826,"description":827,"published":828,"category":667,"image":829,"draft":671},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": zwei Limits, ein Fehlercode","Supabase \"Email Rate Limit Exceeded\" begrenzt jede E-Mail deines Projekts: 2 pro Stunde beim eingebauten Absender. Was zählt und wie du es anhebst.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":831,"title":832,"description":833,"published":834,"category":667,"image":835,"draft":671},"\u002Fblog\u002Fsupabase-users-logged-out","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 Ursachen","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" meldet deine Nutzer ab. Drei Ursachen, und wie das Auth-Log sie trennt.","2026-10-19","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",{"path":837,"title":838,"description":839,"published":840,"category":667,"image":841,"draft":671},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": drei Ursachen","Supabase \"permission denied for schema public\" heißt: Ein Grant auf das Schema fehlt. Was ihn entfernt hat und welche Zeile ihn zurückbringt.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":843,"title":844,"description":845,"published":846,"category":667,"image":847,"draft":671},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": die drei Dinge, die es bedeutet","Supabase \"Bucket not found\" ist eins von drei Dingen: ein öffentlicher Link zu einem privaten Bucket, ein ungenauer Name oder das falsche Projekt.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":849,"title":850,"description":851,"published":852,"category":667,"image":853,"draft":671},"\u002Fblog\u002Fsupabase-invalid-jwt","Supabase invalid JWT: Welcher Schlüssel streikt hier?","Ein Supabase invalid JWT ist PGRST301: ein signiertes Token hat die Prüfung nicht bestanden. In neueren Projekten ist das die Sitzung, nicht der API-Schlüssel.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":855,"title":856,"description":857,"published":858,"category":667,"image":859,"draft":671},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" heißt meist: keine Zeilen","Supabase gibt PGRST116 zurück, \"JSON object requested, multiple (or no) rows returned\", wenn die Abfrage nichts fand. Versteckte Zeilen wirken fehlend.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":861,"title":862,"description":863,"published":864,"category":667,"image":865,"draft":671},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" in Supabase: wo du nachsiehst","\"Database error saving new user\" heißt: etwas an deiner Supabase-Registrierung ist fehlgeschlagen. Der echte Fehler steht in deinen Logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":867,"title":868,"description":869,"published":870,"category":667,"image":871,"draft":671},"\u002Fblog\u002Fwhat-is-supabase","Was ist Supabase? Die Datenbank, die dein Builder ausgesucht hat","Was ist Supabase: die Datenbank, der Login und der Dateispeicher hinter deiner App. Supabase betreibt die Server, die Regeln zu deinen Zeilen gehören dir.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":873,"title":874,"description":875,"published":876,"category":667,"image":877,"draft":671},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Ein offengelegter AWS-Schlüssel im Frontend ist kein OpenAI-Key","Ein im Frontend offengelegter AWS-Zugriffsschlüssel liest und schreibt deinen Speicher. Die Lösung ist meist eine presigned URL, kein neuer Schlüssel.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":879,"title":880,"description":881,"published":882,"category":667,"image":883,"draft":671},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" beim Upload","\"New row violates row-level security policy for table objects\" heißt: Deinem Upload fehlt eine insert-Regel. Ein öffentlicher Bucket fügt keine hinzu.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":885,"title":886,"description":887,"published":888,"category":667,"image":889,"draft":671},"\u002Fblog\u002Fbase44-security-scan","Base44 Security Scan: das, was nur er sehen kann","Der Base44 Security Scan prüft sieben Arten von Problemen von innen. Hier ist die Hälfte, die er liest und sonst niemand, und die Hälfte, die er nie ansieht.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":891,"title":892,"description":893,"published":894,"category":667,"image":895,"draft":671},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Dein API-Key wurde geleakt. Die richtige Reihenfolge","Ein API-Key wurde geleakt und du weißt nicht, was zuerst zu tun ist. Nicht jeder Key im Frontend ist ein Leck, und die Reihenfolge zählt mehr als das Tempo.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":897,"title":898,"description":899,"published":900,"category":667,"image":901,"draft":671},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" ohne RLS abzuschalten","\"Infinite recursion detected in policy for relation\" heißt: Deine Policy hat die Tabelle gefragt, die sie schützt. So brichst du den Kreis.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":903,"title":904,"description":905,"published":906,"category":667,"image":907,"draft":671},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" in Supabase, und die falsche Lösung","\"No API key found in request\" heißt, deine Supabase-Anfrage kam ohne Schlüssel an. Die meisten Antworten zeigen stattdessen auf deine Datenbankregeln.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":909,"title":910,"description":911,"published":912,"category":667,"image":913,"draft":671},"\u002Fblog\u002Fis-base44-safe","Ist Base44 sicher? Was 5.442 echte Base44-Apps zeigten","Ist Base44 sicher? Wir haben 5.442 laufende Base44-Apps mit neun Checks geprüft. Fast alle bekamen ein B, aus Gründen, die der Inhaber nie gewählt hat.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":915,"title":916,"description":917,"published":918,"category":667,"image":919,"draft":671},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","API-Schlüssel verstecken: ab in eine Supabase Edge Function","Einen API-Schlüssel verstecken heißt, ihn aus dem Browser zu nehmen. Eine Supabase Edge Function ist der kleinste Ort dafür, und zwei Schritte zählen mehr.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":921,"title":922,"description":923,"published":924,"category":667,"image":925,"draft":671},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Ist deine .env-Datei öffentlich? Zwölf Pfade zum Prüfen","Ist deine .env-Datei auf deinem eigenen Webserver öffentlich? Zwölf Adressen sagen es dir, und ein Treffer heißt: alles darin ist längst öffentlich.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":927,"title":928,"description":929,"published":930,"category":667,"image":931,"draft":671},"\u002Fblog\u002Fis-v0-safe","v0-Sicherheit: alle 1.790 gescannten v0-Apps bekamen ein A","v0-Sicherheit, gemessen an 1.790 laufenden v0-Apps: Jede bekam ein A. Nur 17 nannten eine Datenbank, und genau das misst das A vor allem.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":933,"title":934,"description":935,"published":936,"category":667,"image":937,"draft":671},"\u002Fblog\u002Fis-bolt-safe","Ist Bolt sicher? Was 1.123 echte Bolt-Apps zeigten","Ist Bolt sicher? Wir haben 1.123 laufende Bolt-Apps mit neun Checks geprüft. Das Hosting war sauber. Die Funde waren Schlüssel und offene Tabellen in den Apps.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":497,"title":939,"description":940,"published":941,"category":667,"image":942,"draft":671},"Ist Supabase down oder liegt es an deiner App? So erkennst du es","Ist Supabase down oder liegt es an deiner App? Ein pausiertes Projekt, eine volle Datenbank und ein eigener Fehler sehen gleich aus. Vier Prüfungen helfen.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":944,"title":945,"description":946,"published":947,"category":667,"image":948,"draft":671},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Verschlüsselt Supabase meine Daten? Ja. Wovor das schützt","Verschlüsselt Supabase Daten? Ja: AES-256 im Ruhezustand, TLS bei der Übertragung, SOC 2 und ISO 27001. Was jedes abdeckt und welches Leck keines stoppt.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":950,"title":951,"description":952,"published":953,"category":667,"image":954,"draft":671},"\u002Fblog\u002Fsupabase-free-plan-limits","Supabase Gratis-Tarif: die Limits und was an jedem passiert","Die Limits des Supabase-Gratis-Tarifs: 500 MB Datenbank, 5 GB Egress und keine Backups. Was an jeder Grenze passiert und was $25 für Pro ändern.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":956,"title":957,"description":958,"published":959,"category":775,"image":960,"draft":671},"\u002Fblog\u002Ftest-your-supabase-backup","Teste dein Supabase-Backup, bevor du es brauchst","So testest du dein Supabase-Backup: in ein Übungsprojekt einspielen, Zeilen zählen, anmelden und die Zeile suchen, die einer abgeschnittenen Datei fehlt.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":962,"title":963,"description":964,"published":965,"category":775,"image":966,"draft":671},"\u002Fblog\u002Fsupabase-backup-github-action","Kostenloses Supabase-Backup per GitHub Action, mit Haken","Eine Supabase-Backup-GitHub-Action kostet nichts und passt für viele Apps. Der Workflow, der richtige Connection String und das Egress pro Lauf.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":968,"title":969,"description":970,"published":971,"category":775,"image":972,"draft":671},"\u002Fblog\u002Fdownload-your-supabase-backup","Warum du dein Supabase-Backup nicht herunterladen kannst","Dein Supabase-Backup kannst du auf aktuellen Projekten nicht herunterladen, weil die Tageskopie physisch ist. Wie du es prüfst und selbst eine Kopie hältst.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":974,"title":975,"description":976,"published":971,"category":667,"image":977,"draft":671},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": der fehlende Grant","Ab 30. Oktober antwortet eine neue Supabase-Tabelle mit \"permission denied for table\", bis du Zugriff erteilst. Der Grant aus der E-Mail ist die halbe Lösung.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":979,"title":980,"description":981,"published":982,"category":667,"image":983,"draft":671},"\u002Fblog\u002Fopen-api-endpoint-exposed","Ist ein offener API-Endpunkt ein Sicherheitsproblem? Sieh ins JSON","Dein Scan hat einen offenen API-Endpunkt gemeldet. Ob das zählt, hängt davon ab, was zurückkam, und die meisten hier gehörten der Plattform.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":985,"title":986,"description":987,"published":988,"category":667,"image":989,"draft":671},"\u002Fblog\u002Flovable-security-scan","Lovable Security Scan: das Eine, was er nicht beweist","Lovable Security Scan: was Quick Scan und Deep Scan prüfen, wann welcher läuft, und das Eine, was kein Scan von innen beweisen kann.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":991,"title":992,"description":993,"published":994,"category":775,"image":995,"draft":671},"\u002Fblog\u002Fsupabase-backup-auth-users","Warum in deinem Supabase-Dump keine Nutzer stehen","Führe supabase db dump allein aus und du bekommst die Form deiner Datenbank und keine einzige Zeile, und das auth-Schema mit deinen Nutzern fehlt ganz.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":997,"title":998,"description":999,"published":1000,"category":667,"image":1001,"draft":671},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domain abgelaufen, Website offline: was jetzt passiert","Deine Domain ist abgelaufen und deine Website ist offline. Welche Frist jetzt läuft, warum das Zertifikat das kleinere Problem ist, und wie du beides prüfst.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":1003,"title":1004,"description":1005,"published":1006,"category":667,"image":1007,"draft":671},"\u002Fblog\u002Fis-lovable-safe","Ist Lovable sicher? Was 18.554 echte Lovable-Apps zeigten","Ist Lovable sicher? Wir haben 18.554 laufende Lovable-Apps mit neun Checks geprüft. Die Plattform war die sauberste von fünf. Die Funde saßen in den Apps.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":1009,"title":1010,"description":1011,"published":1012,"category":667,"image":1013,"draft":671},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Die Sicherheits-Checkliste für Vibe-Coding, in neun Prüfungen","Eine Sicherheits-Checkliste für Vibe-Coding mit neun Punkten, die jeder von außen an deiner Live-App nachprüfen kann, jeder mit einem Test in einer Zeile.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":1015,"title":1016,"description":1017,"published":1018,"category":667,"image":1019,"draft":671},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Ein geheimer Stripe-Schlüssel im Frontend kann Geld bewegen","Ein geheimer Stripe-Schlüssel im Frontend kann erstatten, abbuchen und jeden Kundendatensatz lesen, den du hast. Dein pk_live_-Schlüssel gehört dorthin.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":1021,"title":1022,"description":1023,"published":1024,"category":667,"image":1025,"draft":671},"\u002Fblog\u002Fvite-and-next-public-env-vars","Vite-Env-Variablen offengelegt: der Präfix heißt veröffentlichen","Vite-Env-Variablen offengelegt: Deine App hat getan, was der Präfix verlangt. VITE_ und NEXT_PUBLIC_ heißen veröffentlichen, und die KI kannte den Preis nie.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":1027,"title":1028,"description":1029,"published":1030,"category":667,"image":1031,"draft":671},"\u002Fblog\u002Fbase44-source-maps","Base44-Sicherheit: was ein Scan meldet und was du ändern kannst","Base44-Sicherheit auf 5.438 gescannten Apps: Drei Befunde auf fast jeder gehören der Plattform, die Source Map ist das Base44-Badge, und deine Liste ist kurz.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":1033,"title":1034,"description":1035,"published":1036,"category":667,"image":1037,"draft":671},"\u002Fblog\u002Fis-cursor-ai-safe","Ist Cursor AI sicher? Editor, Code und die App, die du veröffentlichst","Ist Cursor AI sicher? Drei Fragen in einer Suche: was Cursor behält, was sein Code falsch macht und ob deine veröffentlichte App offen steht.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":1039,"title":1040,"description":1041,"published":1042,"category":667,"image":1043,"draft":671},"\u002Fblog\u002Fis-replit-safe","Ist Replit sicher? Was wir in 3.042 Replit-Apps gefunden haben","Ist Replit sicher? Wir haben 3.042 laufende Replit-Apps mit neun externen Checks geprüft. Die Funde saßen in der veröffentlichten App, nicht im Hosting.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":1045,"title":1046,"description":1047,"published":1048,"category":775,"image":1049,"draft":671},"\u002Fblog\u002Fsupabase-storage-backup","Supabase Storage Backup: deine Datenbankkopie hat keine Dateien","Ein Supabase Storage Backup ist eine eigene Aufgabe. Datenbank-Backups enthalten die Liste deiner Dateien und keine davon, also bleibt jeder Upload kaputt.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":1051,"title":1052,"description":1053,"published":1054,"category":775,"image":1055,"draft":671},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Supabase Point-in-Time Recovery: Kosten und Grenzen","Supabase Point-in-Time Recovery spult deine Datenbank auf jede Sekunde der letzten Woche zurück. $100 im Monat zusätzlich zu Pro, und nur die Datenbank.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":1057,"title":1058,"description":1059,"published":1060,"category":775,"image":1061,"draft":671},"\u002Fblog\u002Fsupabase-project-paused-recover","Supabase-Projekt pausiert? Deine Daten sind noch da","Supabase hat dein Projekt nach einer Woche ohne Aktivität pausiert. Gelöscht ist nichts, Wiederherstellen steht neben dem Namen, und du hast ein Jahr.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":1063,"title":1064,"description":1065,"published":1066,"category":667,"image":1067,"draft":671},"\u002Fblog\u002Fsafest-ai-app-builder","Welcher KI-App-Builder ist am sichersten? 30.998 Apps im Test","Welcher KI-App-Builder ist am sichersten? Wir haben 30.998 aktive Apps von Lovable, Base44, Replit, v0 und Bolt gescannt. Der Builder entscheidet das nicht.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":1069,"title":1070,"description":1071,"published":1072,"category":667,"image":1073,"draft":671},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Row Level Security für jede Supabase-Tabelle aktivieren und prüfen","Row Level Security in Supabase ohne Policy sperrt eine Tabelle komplett. Eine Policy ohne den Schalter bringt gar nichts. Hier ist das SQL, und der Test.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":1075,"title":1076,"description":1077,"published":1078,"category":667,"image":1079,"draft":671},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": was die Warnung übersieht","Supabase meldet \"RLS disabled in public\" als Fehler. Zur Lese-Policy, die deine Tabelle genauso offen lässt, sagt der Advisor gar nichts.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":1081,"title":1082,"description":1083,"published":1084,"category":667,"image":1085,"draft":671},"\u002Fblog\u002Frotate-supabase-service-role-key","Geleakten Supabase-service_role-Schlüssel richtig tauschen","Supabase sagt: erst das Leck schließen. Andere Anleitungen: sofort tauschen. Was richtig ist, hängt davon ab, wohin dein service_role-Schlüssel gelangt ist.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":1087,"title":1088,"description":1089,"published":1090,"category":667,"image":1091,"draft":671},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Vibe-Coding-Security-Scanner im Vergleich, unserer eingeschlossen","Der beste Vibe-Coding-Security-Scanner hängt an drei Fragen, die keine Funktionsliste beantwortet. Acht Tools im Vergleich, mit Preisen und unseren Lücken.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1093,"title":1094,"description":1095,"published":1096,"category":667,"image":1097,"draft":671},"\u002Fblog\u002Fsupabase-security-checker","Supabase Security Checker: die fünf Prüfungen selbst machen","Ein Supabase Security Checker liest deine veröffentlichte App statt deiner Projekteinstellungen. Hier sind die fünf Prüfungen und wie du jede selbst ausführst.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1099,"title":1100,"description":1101,"published":1102,"category":667,"image":1103,"draft":671},"\u002Fblog\u002Fvibe-coding-security-scanner","Vibe-Coding-Security-Scanner: was ein URL-Scan übersieht","Ein Vibe-Coding-Security-Scanner liest deine laufende App von außen. Was das abdeckt, die vier Dinge, die er nicht sehen kann, und wie du das Ergebnis liest.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1105,"title":1106,"description":1107,"published":1108,"category":667,"image":1109,"draft":671},"\u002Fblog\u002Fmissing-security-headers","Fehlende Sicherheitsheader: wann sie wirklich zählen","Fehlende Sicherheitsheader ist unser häufigster Befund. Wogegen sie schützen, und wann sie die unwichtigste Zeile in deinem Bericht sind.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1111,"title":1112,"description":1113,"published":1114,"category":667,"image":1115,"draft":671},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Dein OpenAI-API-Schlüssel liegt im Frontend. Tausch ihn aus.","Ein OpenAI-API-Schlüssel im Frontend lässt sich an keine Domain binden. Tausch ihn heute, leg den Aufruf hinter deinen Server und begrenze das Budget.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1117,"title":1118,"description":1119,"published":1120,"category":667,"image":1121,"draft":671},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","API-Schlüssel im Frontend: was 30.998 Apps wirklich ausliefern","Ein API-Schlüssel im Frontend ist meistens ein Google-Maps-Schlüssel. Wir haben 30.998 aktive Vibe-Coding-Apps gescannt und gezählt, was wirklich austritt.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":1123,"title":1124,"description":1125,"published":1126,"category":775,"image":1127,"draft":671},"\u002Fblog\u002Fsupabase-backup-tools-compared","Supabase-Backup-Tools im Vergleich, unseres eingeschlossen","Vier Arten von Supabase-Backup-Tool, was jedes wirklich kopiert und wann eine kostenlose GitHub Action jeden Anbieter schlägt, uns eingeschlossen.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1129,"title":1130,"description":1131,"published":1132,"category":667,"image":1133,"draft":671},"\u002Fblog\u002Freplit-secrets-explained","Secrets in Replit nutzen, und was trotzdem veröffentlicht wird","Secrets in Replit nutzen: anlegen, auslesen und die zwei Gründe beheben, warum undefined zurückkommt. Dazu die Schlüssel, die das Werkzeug nicht schützt.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1135,"title":1136,"description":1137,"published":1138,"category":775,"image":1139,"draft":671},"\u002Fblog\u002Fback-up-supabase-free-tier","Supabase Gratis-Tarif: Backup ohne Terminal selbst machen","Im Supabase Gratis-Tarif gibt es keine Backups, die Kopie musst du selbst machen. Wie das im Dashboard geht und was der CSV-Weg auslässt.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1141,"title":1142,"description":1143,"published":1144,"category":667,"image":1145,"draft":671},"\u002Fblog\u002Fis-supabase-secure","Ist Supabase sicher? Ja. Dein Projekt ist eine eigene Frage","Ist Supabase sicher? Die Plattform ist auditiert, verschlüsselt und pentestet. Supabase schreibt selbst auf, wo das aufhört und deine Einstellungen anfangen.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":399,"title":1147,"description":1148,"published":1149,"category":667,"image":1150,"draft":671},"Wo du deine Supabase API-Keys findest: anon, service_role, URL","Projekt-URL, anon-Schlüssel und service_role-Schlüssel liegen auf einer Seite im Dashboard. Wo sie ist, und welcher der vier Werte in deine App gehört.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1152,"title":1153,"description":1154,"published":1155,"category":667,"image":1156,"draft":671},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy in Supabase: was jetzt?","\"New row violates row-level security policy\" heißt, Supabase hat einen Schreibvorgang abgelehnt. Die schnelle Lösung öffnet die Tabelle wieder für alle.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1158,"title":1159,"description":1160,"published":1161,"category":667,"image":1162,"draft":671},"\u002Fblog\u002Fcors-wildcard-security-risk","Ist eine CORS-Wildcard ein Sicherheitsrisiko? Meist nicht.","Ist eine CORS-Wildcard ein Sicherheitsrisiko? Meist ist sie die Voreinstellung deines Builders und gibt nichts preis, was dein Server nicht ohnehin herausgab.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":374,"title":1164,"description":1165,"published":1166,"category":775,"image":1167,"draft":671},"Supabase Branching ist kein Backup. Es geht nur vorwärts.","Warum Supabase Branching kein Backup ist: Ein Branch startet ohne deine Daten, und ein Merge bringt nur das Schema. Wofür es gut ist und was stattdessen hilft.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":1169,"title":1170,"description":1171,"published":1172,"category":775,"image":1173,"draft":671},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Supabase-Backup wiederherstellen, und was danach kaputt ist","Wie du ein Supabase-Backup aus dem Dashboard oder aus einer Dump-Datei wiederherstellst, was ersetzt wird und warum die App danach kaputt sein kann.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1175,"title":1176,"description":1177,"published":1178,"category":667,"image":1179,"draft":671},"\u002Fblog\u002Fsupabase-storage-bucket-public","Dein Supabase-Storage-Bucket ist öffentlich. Ist das ein Problem?","Ein öffentlicher Supabase-Storage-Bucket heißt: Wer die URL einer Datei hat, kann sie öffnen. Er heißt nicht, dass jemand den Inhalt auflisten darf.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1181,"title":1182,"description":1183,"published":1184,"category":667,"image":1185,"draft":671},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Ist ein Google-API-Schlüssel im Frontend ein Problem?","Ein Google-API-Schlüssel im Frontend ist der Fund unseres Scanners Nummer eins, und meistens unbedenklich. Eine kostenlose Einstellung entscheidet darüber.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1187,"title":1188,"description":1189,"published":1190,"category":775,"image":1191,"draft":671},"\u002Fblog\u002Fai-agent-deleted-my-database","Ein KI-Agent hat meine Supabase-Daten gelöscht. Was hole ich zurück?","Ein KI-Agent hat Daten aus deiner Datenbank gelöscht. Was du zurückholst, stand schon vorher fest, und die nächsten Minuten entscheiden über den Rest.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1193,"title":1194,"description":1195,"published":1196,"category":667,"image":1197,"draft":671},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Kann jeder deine Supabase-Datenbank lesen? 3.680 Apps im Test","Kann jeder deine Supabase-Datenbank ohne Login lesen? Wir haben 30.998 aktive Apps aus KI-Buildern gescannt und gemessen, wie oft die Antwort ja lautet.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1199,"title":1200,"description":1201,"published":1196,"category":667,"image":1202,"draft":671},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source-Maps öffentlich: deine App veröffentlicht ihren Quellcode","Eine öffentliche Source-Map lässt jeden den Originalcode deiner App lesen, Kommentare inklusive. Der 30-Sekunden-Check, und was wirklich zählt.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1204,"title":1205,"description":1206,"published":1207,"category":667,"image":1208,"draft":671},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: ist er derselbe wie der anon key?","Supabase hat anon und service_role durch öffentliche und geheime Schlüssel ersetzt. Welcher gehört in deine App, und welcher nie?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1210,"title":1211,"description":1212,"published":1213,"category":775,"image":1214,"draft":671},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Sichert Supabase meine Datenbank? Das hängt von deinem Tarif ab.","Sichert Supabase deine Datenbank? Auf bezahlten Tarifen täglich, im Gratis-Tarif gar nicht. So findest du heraus, was du hast und was es nicht abdeckt.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1216,"title":1217,"description":1218,"published":1219,"category":667,"image":1220,"draft":671},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security ist an. Die Tabelle ist trotzdem offen.","Supabase Row Level Security anzuschalten schützt keine Tabelle. Erst deine Policies tun das, und die, die deine App repariert hat, lässt oft alle herein.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1222,"title":1223,"description":1224,"published":1219,"category":775,"image":1225,"draft":671},"\u002Fblog\u002Fversion-history-is-not-a-backup","Der Versionsverlauf ist kein Backup. Er holt keine Tabelle zurück.","Lovable und Bolt führen einen Versionsverlauf für deinen Code. Deine Datenbank ist ein eigener Dienst, und ein Rücksprung holt deine Daten nicht zurück.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1227,"title":1228,"description":1229,"published":1230,"category":775,"image":1231,"draft":671},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Drei Wege, eine Supabase-Datenbank zu sichern, und was fehlt","Das Dashboard, pg_dump und ein verwalteter Dienst. Was jeder Weg wirklich sichert, was er stillschweigend auslässt und welcher den Kontoverlust übersteht.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":1233,"title":1234,"description":1235,"published":1230,"category":667,"image":1236,"draft":671},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Welche API-Schlüssel im Frontend sicher sind, und welche nicht","Dein Supabase-anon-Schlüssel darf öffentlich sein. Der service_role-Schlüssel nicht. Er ignoriert jede Regel, die du setzt. So erkennst du den Unterschied.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213638751]