Die meisten Migrationsanleitungen verkaufen den falschen Teil als das Problem. Auth und Storage von Firebase nach Supabase umzuziehen ist Routine – planbar, dokumentiert, in einem Sprint erledigt. Was Projekte sprengt, ist das Datenmodell.
Wer diesen Artikel liest, hat die Grundsatzentscheidung meist schon getroffen: weg von Google Cloud, hin zu Postgres und einem self-hostbaren Stack. Die Gründe dafür – Datensouveränität, Kostenkurve, Vendor-Lock-in – habe ich an anderer Stelle ausführlich behandelt. Hier geht es um die Mechanik. Was tatsächlich passiert, wenn man von Firebase zu Supabase migriert, in welcher Reihenfolge der Schmerz auftritt, und wo das Budget verbrennt, wenn man unvorbereitet startet.
Wer von Firebase zu Supabase migriert, kämpft gegen das Datenmodell
Firestore und Postgres haben grundverschiedene Weltbilder. Firestore ist eine dokumentenorientierte NoSQL-Datenbank, die für Lese-Performance optimiert wird, indem man Daten dupliziert. Man modelliert nicht nach Entitäten und Beziehungen, sondern nach Zugriffsmustern: Was zeigt dieser Screen? Genau das landet in einem Dokument, redundant, denormalisiert, oft mehrfach. Eine Bestellung enthält die Lieferadresse als Kopie, der Nutzername steht in fünf Collections, weil ein Join teuer wäre.
Postgres dreht das um. Eine relationale Datenbank lebt von Normalisierung: eine Wahrheit pro Fakt, verknüpft über Fremdschlüssel. Der Schritt von Firestore zu PostgreSQL ist deshalb kein Datentransfer, sondern eine Modellierungsaufgabe. Man übersetzt nicht Zeilen, man entwirft ein Schema neu. Wer mit der Architektur von Supabase noch nicht vertraut ist, findet die Grundlagen in meinem Überblick, was Supabase technisch ausmacht.
Der offizielle Migrations-Guide macht das ehrlich sichtbar. Er beschreibt das Werkzeug als etwas, das „den gesamten Inhalt einer einzelnen Firestore-Collection in eine einzelne Postgres-Tabelle kopiert" (Supabase-Dokumentation zur Firestore-Datenmigration). Drei Node-Skripte erledigen den Export, die JSON-Konvertierung und den Import. Verschachtelte Felder landen per Default in einer jsonb-Spalte. Das funktioniert – aber es produziert Postgres-Tabellen, die innen noch wie Firestore aussehen. Eine Collection, eine Tabelle, der Rest als JSON-Blob.
Das ist kein relationales Modell. Es ist Firestore in einem Postgres-Kostüm. Wer es dabei belässt, verschenkt genau die Stärken, für die er migriert: Joins, Constraints, Integrität, echte Abfragen. Das saubere Remodeling – Collections aufbrechen, Beziehungen explizit machen, jsonb dort behalten, wo es Sinn ergibt, und nur dort – ist Handarbeit und Kopfarbeit. Und es ist der Posten, an dem die Stunden auflaufen.
Firebase Auth Migration: weniger dramatisch als gedacht
Die gute Nachricht, die in den meisten Diskussionen untergeht: Die Firebase Auth Migration ist kein Bruch für die Nutzer. Niemand muss sein Passwort zurücksetzen, wenn man es richtig macht.
Der Grund liegt in der Architektur von Supabase Auth, intern GoTrue. GoTrue verifiziert Firebase-scrypt-Hashes nativ über einen Dispatcher, der am $fbscrypt$-Prefix erkennt, welches Hash-Verfahren ein gespeichertes Passwort verwendet – neben bcrypt und Argon2. Praktisch heißt das: Man exportiert die Nutzer aus Firebase, importiert sie samt Hash, und die Anmeldung funktioniert mit dem bestehenden Passwort weiter. Beim nächsten erfolgreichen Login kann Supabase intern auf bcrypt umstellen, den Default für neue Passwörter.
Der Ablauf ist mechanisch. Zwei Skripte aus dem Community-Tooling firebase-to-supabase erledigen die Arbeit: eines exportiert die User als JSON, eines importiert sie. Wichtig dabei: Man muss vier SCRYPT-Parameter aus der Firebase-Console kopieren – base64_signer_key, base64_salt_separator, rounds und mem_cost. Ohne diese vier Werte kann GoTrue die Hashes nicht verifizieren.
Genau hier sitzt der einzige relevante Fallstrick der Auth-Migration. Es gibt einen dokumentierten Bug, bei dem falsch importierte Hashes mit leerem encrypted_password-Feld in der Datenbank landen. Das Ergebnis: Jeder Login schlägt fehl, obwohl die Nutzer scheinbar vorhanden sind. Der Fix ist der korrekte $fbscrypt$-Import-Pfad. Wer den offiziellen Pfad nutzt und vorher mit einem Testnutzer prüft, trifft das Problem gar nicht erst. Auth ist planbar, wenn man es plant – nicht weil es trivial ist, sondern weil der Weg vollständig dokumentiert und das Verhalten deterministisch ist. Wer statt Passwort-Login auf einen eigenen Identity-Provider setzen will, sollte parallel die Keycloak-Option als Auth-Layer prüfen.
Ein Hinweis zum Tooling: firebase-to-supabase ist ein Community-Repo, nicht Supabase-Core. Es deckt Auth, Firestore, Storage und Functions ab, wird aber community-getragen gepflegt, nicht als managed Produkt. Für einen Produktiv-Umzug heißt das: Skripte vorher lesen, in einer Staging-Umgebung durchspielen, nicht blind auf der Live-Datenbank ausführen.
Firebase Storage Migration und die Sache mit den privaten Buckets
Die Firebase Storage Migration folgt einem simplen Zwei-Phasen-Muster: herunterladen, hochladen. Dateien aus Firebase Storage exportieren, in Supabase-Buckets schreiben. Bei großen Beständen arbeitet man mit Pagination und Batches, sonst läuft man in Speicher- oder Timeout-Grenzen.
Der eine Punkt, der Teams überrascht: Neue Supabase-Buckets sind per Default privat. Bei Firebase regelt der Zugriff oft eine Security Rule, und vieles ist faktisch öffentlich lesbar. Zieht man Dateien nach Supabase und vergisst, die Zugriffsregeln explizit zu setzen, sind plötzlich alle Avatare, Vorschaubilder und PDFs nicht mehr erreichbar – oder, beim umgekehrten Fehler, öffentlich, wo sie es nicht sein sollten. Das ist kein technisches Problem, sondern eine Checklisten-Frage. Man entscheidet pro Bucket bewusst: privat mit signierten URLs oder öffentlich. Genau das ist der Sicherheitsgewinn, wenn man ihn nutzt.
Storage ist damit, wie Auth, ein gelöstes Problem. Aufwand: überschaubar und linear zur Datenmenge. Risiko: gering, solange man die Default-Privatheit kennt.
Migration Fallstricke: Security Rules und Realtime
Die wahren Migration Fallstricke verstecken sich an zwei Stellen – und beide hängen am Konzept, nicht am Transfer.
Firestore Security Rules sind pfadbasiert. Man schreibt Regeln entlang der Dokumentpfade, in einer eigenen DSL, die Zugriff je nach request.auth und Dokumentinhalt erlaubt oder verweigert. In Supabase übersetzt sich das in Row Level Security: SQL-Policies pro Tabelle, getrennt nach SELECT, INSERT, UPDATE und DELETE. Das ist kein Suchen-und-Ersetzen. Die pfadbasierte Logik muss als relationale Bedingung neu gedacht werden – „darf Nutzer X dieses Dokument sehen" wird zu „welche Zeilen dieser Tabelle gibt die Policy für auth.uid() frei".
Der Gewinn ist beträchtlich, wenn man ihn versteht. RLS filtert nicht nur direkte Abfragen, sondern auch Realtime-Subscriptions automatisch mit. Eine korrekt geschriebene Policy schützt damit den Read-Zugriff über alle Kanäle hinweg – ein architektonischer Vorteil, den Firestore-Rules in dieser Form nicht bieten. Warum Row Level Security mehr als ein Sicherheitsfeature ist und wie man Policies sauber strukturiert, habe ich in einem eigenen Artikel über RLS als Game Changer beschrieben. Für die Migration gilt: Plant Zeit ein, die komplette Regellogik neu zu schreiben und zu testen. Das ist kein Nebenbei-Task.
Der zweite konzeptionelle Bruch ist Realtime. Firestores onSnapshot ist mehr als ein Live-Update: Es bringt einen lokalen Offline-Cache und Conflict-Resolution mit, die App funktioniert ohne Netz weiter und synchronisiert später. Supabase Realtime streamt Postgres-WAL-Änderungen über WebSockets (Dokumentation zu Postgres Changes) – schnell und sauber, aber ohne native Offline-Persistenz. Wer Firestores Offline-Verhalten gebraucht hat, baut das Client-Caching selbst, etwa mit TanStack Query. Für eine klassische Web-App ist das oft kein Thema. Für eine offline-first Mobile-App ist es ein eigener Implementierungsblock, der die Migration spürbar verteuert.
Wie tief steckt die App im Firebase-Ökosystem?
An dieser Stelle muss ich die Gegenposition fair benennen, weil sie in vielen Fällen recht hat. Nutzt eine App nur Firestore, Firebase Auth und Storage, ist der Umzug ein klar umrissenes Projekt. Sitzt sie aber tief im Firebase-Mobile-Ökosystem, ändert sich die Rechnung grundlegend.
FCM für Push-Benachrichtigungen, Crashlytics für Crash-Reporting, Remote Config für Feature-Flags, ML Kit für On-Device-Modelle, Firebase Analytics – für diese Dienste gibt es kein direktes Supabase-Pendant. Supabase hat keinen eigenen Push-Service; Push läuft weiter über FCM oder APNs, angestoßen aus Edge Functions. Die Migration entfernt die FCM-Abhängigkeit also nicht, sie verschiebt nur, von wo aus man sie aufruft. Crashlytics, Remote Config und ML Kit haben kein Gegenstück – man ersetzt sie über Drittanbieter wie Sentry oder behält für diese Teile schlicht Firebase.
Das ist der ehrliche Kern des Zielkonflikts: Je mehr eine App diese Mobile-spezifischen Bausteine nutzt, desto weiter entfernt sich die Migration vom reinen Datenbank-Wechsel. Aus „Firestore zu PostgreSQL" wird dann „Firestore zu PostgreSQL plus FCM neu verdrahten plus Crashlytics ersetzen plus Remote Config nachbauen". Diese Posten muss man einzeln bewerten, bevor man ein Budget nennt. Eine Teilmigration – Datenbank nach Supabase, Mobile-Telemetrie bei Firebase – ist in solchen Fällen oft die wirtschaftlich saubere Lösung, kein Kompromiss aus Schwäche.
Was eine Migration realistisch kostet
Zahlen ohne Kontext sind wertlos, deshalb der Rahmen vorweg. Eine saubere Erstimplementierung eines self-hosted Supabase-Stacks – Setup, Integration, Security, Testing – liegt erfahrungsgemäß bei einmalig 5.000 bis 20.000 Euro Entwicklungsaufwand. Eine Migration kommt obendrauf und verteilt sich höchst ungleich.
Auth und Storage sind die günstigen Blöcke: dokumentiert, deterministisch, in Tagen erledigt. Der Datentransfer selbst – Skripte laufen lassen, Collections kopieren – ist ebenfalls überschaubar. Was die Rechnung treibt, ist das, worüber niemand gern spricht: das Remodeling des Datenmodells, das Neuschreiben der Security Rules als RLS und, falls relevant, der Nachbau von Realtime-Offline-Verhalten und Firebase-Mobile-Features. Bei einem Mischsatz von rund 120 Euro pro Entwicklerstunde entscheidet die Komplexität des Datenmodells, ob eine Migration im unteren oder oberen Bereich der Spanne landet.
Der strategische Punkt dahinter: Die laufenden Kosten eines self-hosted Stacks sinken über die Zeit, während die Kosten von Managed Services mit dem Projekterfolg steigen. Eine Migration ist eine Einmalinvestition gegen eine Kostenkurve, die sich umkehrt. Wie sich das über drei Jahre rechnet und welche Betriebskosten realistisch sind, behandle ich im TCO-Vergleich für Supabase in Produktion. Wer die strategische Gesamtlogik hinter dem Wechsel sucht – warum Supabase für DACH-Organisationen eine ernsthafte Souveränitäts-Option ist –, findet sie auf unserer Supabase-Übersichtsseite.
Manche Apps sollten nicht migrieren
Jetzt der unbequeme Teil, den ich offen sage, obwohl happycoding an Migrationen verdient. Nicht jede Firebase-App gehört nach Supabase. Manche sollten genau dort bleiben, wo sie sind.
Lebt eine App überwiegend von Firebase-spezifischen Mobile-Features – Push, Crashlytics, Remote Config, ML Kit, On-Device-Magie – und steht keine echte Souveränitäts- oder Kostenanforderung dahinter, dann ist eine Migration eine teure Bewegung ohne Ziel. Man tauscht eine funktionierende Architektur gegen eine andere, baut die Hälfte des Firebase-Ökosystems über Umwege nach und zahlt dafür Entwicklungsbudget, das an keiner Stelle einen messbaren Vorteil erzeugt. Man migriert dann für ein Gefühl, nicht für eine Anforderung.
Der ehrliche Test besteht aus zwei Fragen. Erstens: Gibt es einen konkreten Treiber – DSGVO-Druck, ein Datensouveränitäts-Mandat vom Vorstand, eine Firestore-Kostenkurve, die mit dem Erfolg explodiert? Die Datenschutz-Dimension habe ich separat aufgearbeitet, denn auch Google bleibt als US-Konzern dem CLOUD Act unterworfen, trotz EU-Speicherort – nachzulesen in meinem Beitrag über Datenschutz als strategische Entscheidung. Zweitens: Bewegt sich die App überwiegend auf der Datenebene, oder hängt ihr Wert an Mobile-spezifischer Firebase-Infrastruktur? Sitzt der Wert in den Daten und gibt es einen Treiber, lohnt die Migration fast immer. Hängt der Wert an Firebase-only-Features und fehlt der Treiber, ist Bleiben die professionelle Antwort.
Was ich Entscheidern rate
Behandeln Sie die Migration nicht als Datentransfer, sondern als Re-Architektur Ihres Datenmodells – denn genau das ist sie. Auth, Storage und der reine Export sind gelöste Probleme; wer sie als Hauptrisiko einplant, plant am Risiko vorbei. Das Geld und die Zeit fließen ins Remodeling von Firestore-Collections zu normalisierten Postgres-Tabellen, ins Übersetzen der Security Rules in Row Level Security und in alles, was am Firebase-Mobile-Ökosystem hängt.
Bevor irgendein Skript läuft, gehört eine ehrliche Bestandsaufnahme auf den Tisch: Wie tief steckt die App im Ökosystem, wie verschachtelt ist das Datenmodell, gibt es einen strategischen Treiber jenseits von „Postgres klingt besser". Fällt diese Prüfung klar aus, ist die Migration eine der saubersten Investitionen in technologische Souveränität, die man machen kann. Fällt sie unklar aus, ist die mutigere Entscheidung, nicht zu migrieren – und das Budget dort einzusetzen, wo es einen echten Unterschied macht.
