Workspace369: a Flutter and Firebase SaaS for client work
An all-in-one workspace for freelancers and small service businesses: CRM, proposals, invoicing and payments, scheduling, a shared email/SMS/voice inbox, accounting and AI, in one Flutter app on iOS and the web.
Our role: Our own product, designed and built by App369 founder Simon Dziak. Published on the App Store by Workspace369 LLC.
What Workspace369 Needed to Solve
Small service businesses usually run client work across several separate tools: a CRM, a quoting tool, an invoicing app, a booking page, an email inbox and a spreadsheet for the books. Every hand-off between them is a place where a lead, a signature or a payment gets lost. The goal was one product where a client record carries the whole job, from first enquiry to proposal, signed contract, scheduled work, invoice, payment and the bookkeeping entry, with the conversation history attached.
How We Built It
One Flutter codebase serves the iOS app and the web app at app.workspace369.com, with the same screens and business logic on both. Firebase handles sign-in, the Firestore database, file storage, push notifications, crash reporting and App Check. All server logic runs as TypeScript Cloud Functions (2nd gen), split by domain into separately deployed codebases, so a change to payments never redeploys the inbox. Stripe handles subscriptions and client payments, Twilio carries SMS and voice, SendGrid sends and receives email, and Vertex AI powers the AI features. The marketing site is a separate Nuxt app.
What the Product Does
Client record and CRM
Clients, requests and leads in one place, with messages, proposals, invoices and files linked to the client.
Proposals and e-signature
Proposals that clients accept or decline online, follow-ups sent by the server, and contracts with e-signature.
Invoicing and payments
Invoices and estimates rendered to PDF on the server and paid by card through Stripe, including deposits and recurring retainers.
Unified inbox
Email, SMS and voice in one inbox. A workspace can connect several addresses (support@, billing@ and so on), and replies go out from the address the mail came in on.
Scheduling and booking
A public booking page so clients book themselves, Google Calendar sync, and tracked hours that turn into invoice lines.
Client portal
A branded portal where clients can view their projects and documents without another app to install.
Accounting
Double-entry ledger entries written automatically as invoices and payments change.
Automations and AI
Automations triggered by changes to clients, jobs and invoices, AI drafting on Vertex AI, and an MCP server so AI assistants can work inside a workspace.
The Stack, Layer by Layer
- Client app
- Flutter (Dart) with GetX for state and navigation, one codebase for iOS and the web. The repository also carries Android, macOS, Windows and Linux targets.
- Firebase
- Authentication, Cloud Firestore, Cloud Storage, Cloud Messaging, Crashlytics, Performance Monitoring and App Check.
- Backend
- Cloud Functions (2nd gen) on Node.js 22 in TypeScript, organised as 24 separately deployed Firebase codebases (messaging, payments, billing, CRM, accounting, PDF and more). Work that crosses codebases goes through authenticated HTTP calls or Cloud Tasks queues.
- Integrations
- Stripe (billing and client payments), Twilio (SMS and voice), SendGrid (email in and out), Google Calendar, Vertex AI, and Puppeteer for PDF rendering.
- Environments
- A separate staging Firebase project with Stripe in test mode, and a pre-deploy guard that refuses a deploy unless the target project and committed config check out.
Verifiable Facts
Counted from the App Store listing and the source repositories on October 12, 2026. We do not publish user, revenue or growth figures for Workspace369.
What We Learned Shipping It
Split the backend by domain
The backend started as one Firebase codebase with about 450 functions, so every deploy touched everything. Splitting it into per-domain codebases keeps each deploy small. A same-name deploy under a new codebase relabels the existing function in place, so no function URL changed during the move.
Duplicate shared code, then guard the copies
Sharing helpers through a local npm package broke in production: the symlinked package did not survive Firebase deploy bundling. Each codebase now keeps its own copy, and a drift-check script fails if the copies diverge in logic.
Pin Firebase plugin versions
After one firebase_core release regressed, the app pins exact FlutterFire versions and upgrades them together on purpose rather than through a caret range.
Fail open on mail security
Inbound email gets spam, phishing and attachment scanning, but a scanner outage marks the scan as skipped instead of blocking delivery. Losing a customer email is worse than delivering one unscanned.
Planning Something Similar?
We build Flutter and Firebase apps for startups and small businesses. Get a ballpark with our app cost calculator, see Flutter development, or tell us about your project.