Building a real app on Oracle Backend with Firebase APIs
Article Overview
Oracle recently launched Oracle Backend with Firebase APIs — a way to build mobile and web apps on Oracle AI Database with open-source SDKs for auth, document data, storage, security rules, vector search, and App Trust. This post walks through what's in the toolkit, why the design choices matter for DBAs and app teams alike, and a small demo app I built to make it concrete.
Every app team eventually answers the same question: where does the backend come from? For a long time the easy answer was a hosted Backend-as-a-Service — you get authentication, a document store, file handling, and tidy client SDKs on day one, and you start shipping. The catch shows up later. The data that actually runs the company usually lives somewhere colder and more carefully guarded: a governed, audited, encrypted Oracle database the app team never talks to directly. So you end up maintaining two worlds — two data models, two security stories, two homes for user data, and often a separate vector database wired in beside the real system of record.
The pitch, in one line: keep the developer experience that made BaaS pleasant, but let the "service" simply be your database. Below I'll walk through what the toolkit includes, why its design choices are worth a second look, and a small app I wrote to see how it feels in practice.
The short version
The toolkit lets you build straight against Oracle AI Database using client SDKs for iOS, Android, JavaScript, and Flutter. If you've shipped anything on Firebase, the API surface will read like a dialect you already speak. It arrives as a no-cost feature of Oracle REST Data Services (ORDS) 26.1.1, which means it lives wherever your ORDS already lives — Oracle Cloud, AWS, Azure, Google Cloud, on-prem, or Cloud@Customer. You don't provision a new service, and there's no extra control or data plane sitting off to the side of the database.
A document write in the JavaScript SDK looks like this — Firestore veterans will recognize the rhythm immediately:
import { initializeApp } from "fusabase/app"; import { getOracledb, doc, setDoc } from "fusabase/oracledb"; const app = initializeApp({ ords_host: "https://your-ords-host/ords/your-schema/", project_id: "recall", app_id: "web", schema: "your-schema", objs_type: "dbfs", }); const db = getOracledb(app); // Log a fix as a document await setDoc(doc(db, "users", "ava", "entries", "jwt-expiry"), { title: "JWT expired mid-session, users bounced to login", detail: "Added silent refresh on the first 401 and retried once.", tags: ["auth", "jwt", "react"], severity: "med", });
What makes that snippet interesting is invisible from the code: the document you just wrote is a row in Oracle AI Database. It inherits the encryption, auditing, partitioning, and high-availability posture your DBA team already runs. Nothing had to be copied anywhere for that to be true.
What you actually get
A document store that thinks in collections. You organize data as collections, documents, and subcollections, and read it back with the usual where / orderBy / limit grammar. When a new app needs to touch data that already exists in Oracle, you can reach relational tables too — so a greenfield app and a warehouse full of existing tables can share one home instead of one shadowing the other.
Sign-in that sits beside your data. Authentication spans email/password, social providers (Google, Facebook, GitHub), SAML SSO, generic OIDC, LDAP, and Oracle identity domains. Because user and session records live in the same database as everything else, your access rules can point at a user's identity without a bolt-on directory to reconcile. On the client you get onAuthStateChanged, sign-in and sign-out, and token helpers — and the identity token rides along on every call after you're authenticated.
File storage on the same access model. Uploads, downloads, listings, and deletes flow through storage references, with the bytes landing in DBFS or OCI Object Storage depending on how the project is wired. The same declarative rules that guard your documents guard those file paths, so records and files answer to one policy in one place.
Rules that run inside the database. Access control is written declaratively against your collections, documents, and storage paths — and, crucially, it's evaluated within Oracle AI Database, right where the data sits, with no side-car policy engine to babysit. Since a collection is a genuine database object, everything your DBAs already put in place keeps working: a Virtual Private Database policy on the underlying table still fires on every read and write, next to the app-level rules. The two layers coexist; adopting the toolkit doesn't switch off the controls your data team depends on.
Vector search parked next to your records. Oracle AI Database 26ai carries native vector storage and similarity search in the engine itself, and the SDK surfaces both. You attach dense or sparse embeddings to the very documents they describe, then rank them with a findNearest call shaped like the rest of the API:
import { collection, query, findNearest, getDocs } from "fusabase/oracledb"; const q = query( collection(db, "users", "ava", "entries"), findNearest("embedding", { vector: queryEmbedding }, { metric: "COSINE", topK: 5 }) ); const results = await getDocs(q);
Since those vectors share a database with the rest of your data, similarity ranking, ordinary filters, and joins to relational tables all resolve in one query under one set of rules — and there's no standalone vector store to secure or resynchronize. That single detail is most of the argument for the whole approach.
App Trust — a check that the caller is really your app. Rules can establish who is making a request; they can't, by themselves, prove the request came from your genuine app rather than a script replaying the same public config. App Trust plugs that hole with a per-request attestation token, and at launch you choose the provider — reCAPTCHA v3, reCAPTCHA Enterprise, hCaptcha, or Cloudflare Turnstile. You initialize it once at startup and every later call carries the token automatically; the backend then turns away anything that shows up without one. In practice that means scripted floods get filtered before they reach the database, a cloned front end built from a lifted config can't talk to the real backend, bots can't burn your compute budget on heavy queries, and credentials harvested by a fake sign-in page have nowhere to spend themselves.
SDKs, a Console, and a CLI. There are native SDKs for iOS (Swift), Android (Java), Web (JavaScript/TypeScript), and Flutter. A Console handles the housekeeping — registering apps, managing users and App Trust providers, editing rules, browsing data, configuring storage and vector columns, and setting authorized domains. And a fusabase command-line tool takes care of project setup and scripted workflows.
A note for Firebase developers
This isn't a clone of Firebase, and it doesn't claim to be one. What carries over is the muscle memory: collections, documents, queries, auth-state listeners, declarative rules, and storage references all have direct counterparts, so the everyday motion of assembling an app feels the same. The plot twist is only in what's answering the calls — an enterprise Oracle database rather than a hosted service.
The best part of building it was how little there was to explain. The distance between "a feature in the journal" and "a primitive in the toolkit" is roughly one line. You write an ordinary app, and the governed database is simply underneath it.
Why the design lands
Peel away the friendly SDK and the whole thing is an argument about location:
- One store, not two. Users, documents, files, and vectors all sit in Oracle AI Database. There's nothing to keep in sync because there's no second copy.
- One security model. App-level rules run in the same place as VPD, auditing, and encryption. The app can't quietly sidestep governance, because there's no separate plane to sidestep through.
- AI where the data already is. Retrieval-augmented generation, semantic search, and recommendations can join against trusted records in a single query, with no external vector database to stand up and maintain.
- Nothing new to operate. It rides inside ORDS 26.1.1. If you already run ORDS, you already run this.
For teams that trust Oracle for the data but reached for a BaaS to get nice client SDKs, that particular compromise mostly evaporates.
Try it yourself
Oracle Backend with Firebase APIs is generally available now, free, as part of ORDS 26.1.1.
Free hands-on workshops on Oracle LiveLabs:
Starting a new app on Oracle AI Database and want a direct line to the people building the toolkit? Please contact us we can support.
What ships next is being steered by the apps people are actually building on it.
Comments