Documentation Index
Fetch the complete documentation index at: https://docs.modaal.dev/llms.txt
Use this file to discover all available pages before exploring further.
What is Firebase for?
Firebase is Google’s backend-as-a-service for mobile apps. You don’t run servers, manage databases, or write auth flows from scratch — Firebase gives you all of that through a small set of SDKs. Typical things you’d use it for:Sign-in
Cloud database
File storage
Cloud Functions
Analytics
Crashlytics
Push notifications
Remote Config
Step-by-step setup
Open the Firebase tab in Modaal (the flame icon in the left sidebar of your project). The panel walks you through connecting your Google account, picking (or creating) a Firebase project, and wiring the iOS app.Connect your Google account
Install the Firebase CLI (first project only)
firebase command-line tool. Modaal checks whether it’s installed and offers to install it for you if not. Click Install — this runs npm install -g firebase-tools behind the scenes.Pick or create a Firebase project
- Reuse an existing project (e.g., one you already created in the Firebase console for another app) by picking it from the list.
- Create a new one by selecting — Create Project — at the top of the dropdown. Modaal creates it under your Google account using the
firebase projects:createCLI command.
Register your iOS app
xcodegen.yml) against the iOS apps registered in the Firebase project.- If there’s a match, you’re done — Modaal downloads
GoogleService-Info.plist, drops it intosrc-ios/App/<TargetName>/, and wires it into the Xcode project. - If there’s no match, click Register this app. Modaal registers the bundle id with Firebase and downloads the plist automatically.
(Optional) Enable deployable services
firebase/firebase.json.You can click Initialize Firebase project to turn them all on in one step.Ask your agent to add a feature
“Add Firebase sign-in with Apple, and let users save their favorite recipes to Firestore.”The agent reads Modaal’s Firebase integration knowledge base, picks the right wrappers, writes the Swift code, and runs the build. When it needs something only a human can do — enabling a provider in the Firebase console, uploading an APNs auth key for push — it tells you exactly what to do and where.
How Modaal wires Firebase — and why
Modaal doesn’t drop the vanillafirebase-ios-sdk into your app. It adds a small Swift package called modaal-firebase-wrappers that wraps each Firebase SDK behind a protocol.
Your app depends on ModaalFirebaseAuth, ModaalFirebaseFirestore, etc. — one product per service, each re-exporting the parts of the underlying SDK you need, plus a protocol you can inject and mock.
Why not vanilla firebase-ios-sdk?
Testability — your code no longer depends on Firebase directly
Testability — your code no longer depends on Firebase directly
Firestore directly. That means every unit test needs a real Firestore emulator running, or a tangled manual mock. With ModaalFirebaseFirestore, your screen depends on a FirestoreServiceProtocol. Unit tests inject a fake that returns fixed documents — no emulator, no network, milliseconds per test.Same story for Auth, Functions, Storage, Analytics, and Remote Config. Each one ships a protocol and a ready-made mock you can drop into test targets.Token savings — the agent reads a small wrapper, not the whole SDK
Token savings — the agent reads a small wrapper, not the whole SDK
firebase-ios-sdk is over a million tokens of symbol information across a dozen modules. The agent can’t hold that in context, so it either hallucinates APIs or skips parts of the SDK.Modaal’s wrappers are tiny — a few hundred lines per product. The agent reads the protocols, sees exactly what’s available, and writes code that actually compiles. Fewer retries, faster turns, lower bills.One composition root — swap the real SDK for a fake in tests or previews
One composition root — swap the real SDK for a fake in tests or previews
FirestoreService() (real) for FakeFirestoreService(fixtures: ...) (preview / UI test) is a one-line change. No conditional compilation, no feature flags, no #if DEBUG.This is the same pattern used by RIBs and clean-architecture iOS apps — the wrappers just make it easy for you without writing boilerplate.Stable surface across Firebase SDK upgrades
Stable surface across Firebase SDK upgrades
ModaalFirebaseAuth instead of FirebaseAuth, the upgrade lands in the wrapper — your app code usually doesn’t need to change.What Modaal puts in your project
Typical scenarios
Scenario 1: Add sign-in with Apple + save favorites
You have a working app. You want users to sign in with Apple and save a list of favorites that syncs across their devices.Open the Firebase panel and connect
Enable Apple sign-in in the Firebase console
Ask the agent to implement it
“Add Apple sign-in usingThe agent will:ModaalFirebaseAuth. After sign-in, save the user’s uid to theusers/{uid}document in Firestore. Add a Favorites screen that reads and writesusers/{uid}/favorites.”
- Add the
ModaalFirebaseAuthandModaalFirebaseFirestoreproducts toPackage.swift. - Add a “Sign in with Apple” button and a sign-in flow.
- Add a
FavoritesServicethat talks to Firestore through the protocol. - Add a real-time listener so favorites sync across devices without a refresh button.
- Run the build and fix any errors.
Tighten security rules before you ship
firestore.rules is default-deny for safety. Ask the agent:“UpdateClick Deploy on the Firestore row in the Firebase panel. The rules go live in ~10 seconds.firestore.rulesso users can read and write their ownusers/{uid}/**subtree but nothing else.”
Scenario 2: Catch crashes in production
You’re a week before launch and want to know what breaks on real devices.Enable Crashlytics (one toggle)
“AddThe agent adds the product, initializes it at launch, and wraps yourModaalFirebaseCrashlyticsto the app. Log non-fatal errors from the top-levelcatchbranches inFavoritesService.”
catch blocks with Crashlytics.record(error:). The dSYM upload script was already added when you registered the iOS app, so symbolicated reports arrive automatically.Test the pipe before release
“Add a hidden crashNow() trigger in the Settings screen that forces a crash, so I can verify Crashlytics is catching events end-to-end.”
Build, run on device, crash the app, relaunch. Within a couple of minutes, the crash appears in Firebase Console → Crashlytics.Scenario 3: Send a welcome notification
You want users to receive a push notification the first time they sign in.Enable Cloud Functions (toggle in the panel)
firebase/functions/ with a TypeScript starter.Upload an APNs auth key
.p8 file. Upload it to Firebase Console → Project Settings → Cloud Messaging → Apple apps.Ask the agent to implement
“AddThe agent adds the iOS side (permission request, FCM token registration, foreground handler) and writes the Cloud Function inModaalFirebaseMessagingand request notification permission on first launch. When a new user is created in Firestore (onDocumentCreatedtrigger onusers/{uid}), send them a welcome notification via FCM.”
firebase/functions/src/index.ts.What do I deploy, and when?
When the agent (or you) edits a file under thefirebase/ folder, those changes are local only until you click the matching Deploy button in the Firebase panel. The live app keeps running with the last-deployed version until then.
The Firebase panel’s Deployable services card shows one row per service with a colored dot:
- 🟢 Green — what’s live matches your local files. Nothing to do.
- 🟡 Yellow — you have local changes that haven’t been deployed yet. Click Deploy on that row.
- ⚪ Gray — the service is set up locally but has never been deployed. Click Deploy to publish it for the first time.
- 🔴 Red — the last deploy failed. Click Deploy again; the log window shows what broke.
Changed this? Deploy that.
| You edited or added… | Deploy this | What happens if you skip the deploy |
|---|---|---|
firebase/firestore.rules — who can read/write your database | Firestore rules | The database keeps enforcing the old rules. Users can’t reach new data, or can reach data you meant to lock down. |
firebase/firestore.indexes.json — added a new query in the app | Firestore indexes | New queries silently fail in the app with a “query requires an index” error. |
firebase/storage.rules — who can upload/download files | Storage rules | Same as Firestore rules — old rules stay in effect. |
Anything inside firebase/functions/ — your server-side code | Cloud Functions | Clients keep calling the old version of your function until you redeploy. |
Added an npm package in firebase/functions/package.json | Cloud Functions (after npm install && npm run build) | The function crashes at cold-start because the package isn’t in the deployed bundle. |
Anything in firebase/hosting/public/ — your static site | Hosting | The public site keeps serving the last-deployed content. |
The AASA file (apple-app-site-association) for universal links | Hosting | iOS downloads the AASA from your live site, not from your computer. Until you redeploy, universal links behave however the previous AASA said. |
Changed DEVELOPMENT_TEAM in iOS Project Settings after Hosting was set up | Hosting | Modaal automatically rewrites the AASA locally, but universal links won’t work with the new team id until the Hosting deploy publishes the updated file. |
You do NOT need to deploy after:
- Swift code changes in your iOS app — those go live when you run or ship the iOS app, not through Firebase deploy.
- Swapping the Google account connected to Modaal — that’s just a sign-in change.
- Turning Firebase Analytics events on/off in code — events go live with the next iOS build.
- Enabling Apple / Google / phone sign-in — that’s done in the Firebase Console → Authentication → Sign-in method, not via Deploy.
- Uploading an APNs push key — done in the Firebase Console, not via Deploy.
- Editing Remote Config values — done in the Firebase Console → Remote Config (click Publish there).
Troubleshooting
When something goes wrong with Firebase, the best first move is almost always:Ask the agent to fix it
GoogleService-Info.plist, the wrappers package, the crash-reporting upload step — and fixes whatever’s out of place. For anything that can only be done by a human (like enabling a provider in the Firebase console or upgrading the billing plan), it tells you the exact button to click or URL to open.- Fix Firebase integration — brings your project’s local files back in sync with Firebase (re-downloads the plist, re-links it in the iOS project, re-adds the crash-reporting upload step).
- Migrate to wrappers — if your project still uses the vanilla Firebase SDK directly, this switches it over to the Modaal wrappers without changing how the app behaves.
Common issues
The top banner says Firebase is not connected, even though I just signed in
The top banner says Firebase is not connected, even though I just signed in
'You don't have access to project <name>' error
'You don't have access to project <name>' error
- Click Sign in with a different Google account in the error banner and use the account that owns the project.
- Or ask the project owner to invite you as a member in Firebase Console → Project settings → Users and permissions.
'Firebase CLI not found' or 'firebase login required'
'Firebase CLI not found' or 'firebase login required'
firebase command-line tool, which has its own separate sign-in.Modaal shows a Sign in via Terminal button when this is needed — click it, a terminal opens with firebase login pre-typed, finish the browser flow, click Retry. You only do this once per machine.'Firebase Storage has not been set up' when I click Deploy
'Firebase Storage has not been set up' when I click Deploy
Cloud Functions deploy fails with 'project must be on the Blaze plan'
Cloud Functions deploy fails with 'project must be on the Blaze plan'
Crashes don't appear in Crashlytics
Crashes don't appear in Crashlytics
- Did the app crash on a real device, not the Simulator? (Simulator crashes don’t upload.)
- Did you relaunch the app after the crash? Crashlytics uploads on the next launch, not at crash time.
- Is the
[Firebase Crashlytics] Upload dSYMspost-build script present in your Xcode target? (The Firebase panel’s status banner shows this explicitly. If it’s missing, click Fix Firebase integration.) This script turns raw crash addresses into readable function names — without it, reports show up but you can’t tell where the crash happened.
Apple Universal Links / AASA file has the wrong team id
Apple Universal Links / AASA file has the wrong team id
firebase/hosting/public/.well-known/apple-app-site-association is what tells iOS to open your app when someone taps a link to your site. It’s generated when Hosting is first enabled, using whatever Apple Team was selected at that moment. If you change the team later from the iOS Project Settings panel, Modaal automatically rewrites the AASA file to match. If you edited it by hand before changing the team, re-run Deploy on the Hosting row to publish the refreshed file.I created the Firebase project in the console, but Modaal doesn't see it in the dropdown
I created the Firebase project in the console, but Modaal doesn't see it in the dropdown
I need to roll Firebase back / start over
I need to roll Firebase back / start over
GoogleService-Info.plist, firebase/…, Package.swift, etc.) — your app keeps working and can be re-connected to the same or a different Firebase project later.To remove Firebase from the project entirely, ask the agent:
“Remove all Firebase integration from this project — the wrappers package, the plist, the post-build script, and the firebase/ directory.”