Oracle Backend for Firebase (Fusabase) on a Self-Hosted Dockerized Oracle Database + ORDS Stack

Oracle Backend for Firebase (Fusabase) on a Self-Hosted Dockerized Oracle Database + ORDS Stack

A step-by-step field report: enabling Oracle’s new Firebase-compatible BaaS toolkit on an existing Oracle AI Database 23ai + ORDS 26.1 setup running in separate Docker containers, including every command, every wrong turn, every error message, and a working Flutter app built on top of it at the end.

Environment: Ubuntu 24.04 LTS · Oracle AI Database 26ai (23.26.1.0.0) in Docker · ORDS 26.1.2 in a separate Docker container · Docker network shared between both containers

What is Oracle Backend for Firebase?

Oracle Backend for Firebase, internally referred to as Fusabase, is a free toolkit shipped as part of Oracle REST Data Services (ORDS) 26.1+. It gives mobile and web developers Firebase-style building blocks (Authentication, document-style database access, file storage, security rules, vector search, and an attestation-based App Trust layer) backed directly by an Oracle AI Database, with open-source client SDKs for iOS, Android, Flutter, and JavaScript/Web.

The key architectural point: if you already have ORDS deployed, you don’t need a separate managed plane or data plane. Fusabase runs directly on top of your existing Oracle Database + ORDS installation.

Environment & Prerequisites

Component Value
OS Ubuntu 24.04 LTS
Database image oracle/database:23.26.1-ee (Oracle AI Database 26ai / 23.26.1.0.0)
Database container name database23 (internal hostname: database)
ORDS image ords-26.1:latest (ORDS 26.1.2 Production)
ORDS container name ords26
Docker network database-ords (shared, external network)
Internal DB port 1521 (container-to-container)
External DB port 1522 (host-mapped, for SQL Developer etc., not used for container-to-container traffic)
PDB name ORCLPDB
ORDS config volume named volume ords-config mounted at /etc/ords/config
Official prerequisites (per Oracle docs)

  • Oracle AI Database 23.9 or later
  • ORDS 26.1 or later
  • An account with SYS AS SYSDBA privileges (or a dedicated ORDS installer user)
  • A database account with the DBA role to prepare/enable the project schema
  • The ORDS configuration directory, host, port, and target PDB service name

docker-compose reference

Both containers already existed and were running well before this exercise. The goal was to add the Fusabase feature without breaking the existing APEX/ORDS setup.

Database container

version: '3.9'
services:
  database:
    image: oracle/database:23.26.1-ee
    container_name: database23
    hostname: database
    restart: always
    ports:
      - "1522:1521"
    environment:
      ORACLE_PWD: "<SYS_PASSWORD>"
      ORACLE_CHARACTERSET: "AL32UTF8"
      ORACLE_SID: "ORCL"
      ORACLE_PDB: "ORCLPDB"
    volumes:
      - oracle-23c-data:/opt/oracle/oradata
    networks:
      - database-ords
networks:
  database-ords:
    name: database-ords
volumes:
  oracle-23c-data:
    name: oracle-23c-data

ORDS container

version: '3.9'
services:
  ords:
    image: ords-26.1:latest
    container_name: ords26
    restart: always
    ports:
      - "8282:8080"
    environment:
      DBHOST: database
      DBPORT: 1521
      DBSERVICENAME: ORCLPDB
      ORACLE_PWD: <SYS_PASSWORD>
    volumes:
      - ords-config:/etc/ords/config
      - /home/apex26/images:/opt/oracle/apex/images
    networks:
      - database-ords
networks:
  database-ords:
    external: true
    name: database-ords
volumes:
  ords-config:
    name: ords-config
Important lesson
Both containers sit on the same host, in separate containers, connected through a shared Docker network (database-ords). Container-to-container traffic uses the internal hostname (database) and internal port (1521). The externally mapped port (1522) is irrelevant here. Because ords-config is a named Docker volume and not a container-local path, any configuration written into it, including the Fusabase install, survives container restarts and redeploys via Portainer.

1Check Database Compatibility

Connect as SYS in the CDB root and check the current COMPATIBLE setting and version:

docker exec -it database23 bash
sqlplus / as sysdba
show parameter compatible;
SELECT banner_full FROM v$version;
Result

NAME              TYPE    VALUE
----------------- ------- ------
compatible        string  23.6.0
noncdb_compatible boolean FALSE

"Oracle AI Database 26ai Enterprise Edition Release 23.26.1.0.0 - Production
Version 23.26.1.0.0"

COMPATIBLE = 23.6.0 is below the required 23.9.0. This needs to be raised before continuing.

Also confirm which container you’re currently in. This matters because COMPATIBLE can only be changed from CDB$ROOT:

SELECT SYS_CONTEXT('USERENV','CON_NAME') FROM DUAL;

If this returns your PDB name (e.g. ORCLPDB) instead of CDB$ROOT, switch containers first:

ALTER SESSION SET CONTAINER = CDB$ROOT;

2Raise COMPATIBLE to 23.9.0

From CDB$ROOT:

ALTER SYSTEM SET COMPATIBLE='23.9.0' SCOPE=SPFILE;

This setting only takes effect after a real instance restart. Since the database runs on a Docker named volume and not container-local storage, a SHUTDOWN/STARTUP from within the container is completely safe. The container itself keeps running, only the Oracle instance process cycles.

Tip: do this via a fresh CLI session, not a GUI tool
Running SHUTDOWN/STARTUP or ALTER PLUGGABLE DATABASE ... CLOSE/OPEN through a networked GUI tool (e.g. SQL Developer connecting over the mapped port) can hang or lose the connection mid state-change, because the instance passes through NOMOUNT → MOUNT → OPEN states. Do these operations directly inside the container via a local sqlplus session (bequeath connection) instead:

docker exec -it database23 sqlplus / as sysdba
SHUTDOWN IMMEDIATE;
STARTUP;
Result

Database closed.
Database dismounted.
ORACLE instance shut down.
ORACLE instance started.

Total System Global Area 1.8945E+10 bytes
Fixed Size                 11500648 bytes
Variable Size            4026531840 bytes
Database Buffers         1.4898E+10 bytes
Redo Buffers                8855552 bytes
Database mounted.
Database opened.

NAME       TYPE    VALUE
---------- ------- --------
compatible string  23.9.0

3Enable Extended String Support (32k Types)

Check the current setting inside the PDB:

ALTER SESSION SET CONTAINER=ORCLPDB;
SELECT value FROM v$parameter WHERE name = 'max_string_size';

Result: STANDARD, needs to become EXTENDED.

All ALTER PLUGGABLE DATABASE commands must run from CDB$ROOT, so switch back first:

ALTER SESSION SET CONTAINER=CDB$ROOT;
ALTER PLUGGABLE DATABASE ORCLPDB CLOSE;
Gotcha: this command can appear to “hang”
If run through SQL Developer’s Script Runner, ALTER PLUGGABLE DATABASE ... CLOSE can appear stuck for a long time, typically because active sessions (e.g. from an ORDS connection pool) are still attached to the PDB. Fix: cancel the running SQL Developer script, then check the real status directly from the container:

docker exec -it database23 sqlplus / as sysdba
SELECT name, open_mode FROM v$pdbs;

In this run, the close actually completed fine in the background. The confirmation simply took a while to reach the GUI client.

Once the PDB is confirmed closed, open it in UPGRADE mode and run the Oracle-provided script:

ALTER PLUGGABLE DATABASE ORCLPDB OPEN UPGRADE;
ALTER SESSION SET CONTAINER=ORCLPDB;
ALTER SYSTEM SET max_string_size = extended;
@?/rdbms/admin/utl32k.sql

The script prints several DOC> warning blocks. These describe what error would appear if a prerequisite were missing, they are not errors themselves. Look for the actual outcome lines: PL/SQL procedure successfully completed, 508 rows updated, Commit complete, No errors.

Then return the PDB to normal service and verify:

ALTER SESSION SET CONTAINER=CDB$ROOT;
ALTER PLUGGABLE DATABASE ORCLPDB CLOSE;
ALTER PLUGGABLE DATABASE ORCLPDB OPEN;

ALTER SESSION SET CONTAINER=ORCLPDB;
SELECT value FROM v$parameter WHERE name = 'max_string_size';
Result EXTENDED

4Configure the TDE Wallet

Check whether a working wallet already exists:

ALTER SESSION SET CONTAINER=CDB$ROOT;
SELECT WRL_TYPE, WRL_PARAMETER, STATUS FROM V$ENCRYPTION_WALLET;
Result

WRL_TYPE       FILE
WRL_PARAMETER  /opt/oracle/admin/ORCL/wallet
STATUS         NOT_AVAILABLE

A path is configured but nothing usable exists there yet. Confirmed on disk: the target directory doesn’t even exist (only an unrelated xdb_wallet folder was present, plus an unrelated application-level wallet folder at /opt/oracle/oradata/wallet used by other integrations. Do not confuse the two, they are unrelated to TDE).

Create the wallet directory with correct ownership and permissions (inside the container, plain shell):

mkdir -p /opt/oracle/admin/ORCL/wallet
chown -R oracle:oinstall /opt/oracle/admin/ORCL/wallet
chmod 700 /opt/oracle/admin/ORCL/wallet

Back in sqlplus, set wallet_root and restart the instance for it to take effect:

ALTER SYSTEM SET wallet_root='/opt/oracle/admin/ORCL/wallet' SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
show parameter wallet_root;

Then configure and open the keystore:

ALTER SYSTEM SET tde_configuration='KEYSTORE_CONFIGURATION=FILE' SCOPE=BOTH;

ADMINISTER KEY MANAGEMENT CREATE KEYSTORE
  IDENTIFIED BY "<strong_keystore_password>";

ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN
  IDENTIFIED BY "<strong_keystore_password>" CONTAINER=ALL;

ADMINISTER KEY MANAGEMENT SET KEY
  IDENTIFIED BY "<strong_keystore_password>" WITH BACKUP CONTAINER=ALL;

SELECT WRL_TYPE, WRL_PARAMETER, STATUS FROM V$ENCRYPTION_WALLET;
Result

WRL_TYPE      FILE
WRL_PARAMETER /opt/oracle/admin/ORCL/wallet/tde/
STATUS        OPEN
Security note
Use a real, private password for <strong_keystore_password> in any environment beyond throwaway local dev. Never reuse example or tutorial passwords, and never publish the real value.

5Create the Project-Owning Schema

Every Fusabase project is owned by exactly one schema. Create a dedicated tablespace and user inside the PDB:

ALTER SESSION SET CONTAINER=ORCLPDB;

CREATE TABLESPACE fusabase_tbs
  DATAFILE 'fusabase_tbs01.dbf' SIZE 50M AUTOEXTEND ON
  EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;

CREATE USER fusabase_user IDENTIFIED BY "<password>"
  DEFAULT TABLESPACE fusabase_tbs
  QUOTA UNLIMITED ON fusabase_tbs;

GRANT CREATE SESSION TO fusabase_user;
GRANT RESOURCE TO fusabase_user;
GRANT DBFS_ROLE TO fusabase_user;

Verify:

SELECT username, default_tablespace, account_status
FROM dba_users WHERE username = 'FUSABASE_USER';

SELECT tablespace_name, status
FROM dba_tablespaces WHERE tablespace_name = 'FUSABASE_TBS';

SELECT granted_role FROM dba_role_privs WHERE grantee = 'FUSABASE_USER';
Result User FUSABASE_USER exists, tablespace FUSABASE_TBS is ONLINE, roles RESOURCE and DBFS_ROLE granted.

6Create a Dedicated DBA Admin User

The schema-enablement procedure (OBAAS_ADMIN.OBAAS_ENABLE_SCHEMA) must not be run as SYS. Oracle’s own documentation flags an ORA-06598 error in that case. Create a separate account with the DBA role instead:

CREATE USER fb_admin IDENTIFIED BY "<password>";
GRANT DBA TO fb_admin;
GRANT CREATE SESSION TO fb_admin;

Log in as this new user, over the network this time, to confirm listener and service connectivity, not just a local bequeath connection:

sqlplus fb_admin@localhost:1521/ORCLPDB
Shell gotcha: passwords containing “!”
If your password contains a literal ! (e.g. Password123!) and you try to pass it inline on the command line (sqlplus user/password!@host...), Bash’s history expansion intercepts the ! and throws event not found. Two fixes:

  1. Disable history expansion for the session: set +H
  2. Preferred: don’t put the password on the command line at all. Connect with just the username and let SQL*Plus prompt for the password interactively: sqlplus fb_admin@localhost:1521/ORCLPDB. This also keeps the password out of your shell history.

7Enable the Feature in ORDS

Move to the ORDS container, a separate container from the database, connected via the shared database-ords Docker network:

docker exec -it ords26 bash
ords --version
Result ORDS: Release 26.1 Production ... Oracle REST Data Services 26.1.2.r1401916, meets the 26.1+ requirement.

Before running anything, verify where the ORDS config actually lives. This determines whether the install survives a container recreate:

docker inspect ords26 --format '{{ range .Mounts }}{{ .Source }} -> {{ .Destination }}{{ println }}{{ end }}'
Result

/home/apex26/images -> /opt/oracle/apex/images
/var/lib/docker/volumes/ords-config/_data -> /etc/ords/config

/etc/ords/config is a named Docker volume, not container-local storage, safe to modify, changes persist across container restarts and redeploys.

Run the interactive installer:

ords --config /etc/ords/config fusabase install

Walk through the interactive prompts:

  1. Select the database pool. ORDS auto-detects the existing pool from its own saved configuration:
    [1] default    jdbc:oracle:thin:@//database:1521/ORCLPDB
    Choose [1]: 1

    This is the same connection ORDS has already been using in production for the existing APEX app, confirmed independently with:

    docker exec ords26 env | grep DB
    # DBHOST=database
    # DBPORT=1521
    # DBSERVICENAME=ORCLPDB
  2. Feature configuration. Accept the defaults:
    [1] Enable Feature FUSABASE: Yes
    [2] Encryption passphrase for FUSABASE: <generate>
    Choose [A]: A
  3. Administrator credentials:
    Enter the administrator username: sys as sysdba
    Enter the database password for sys as sysdba: <type manually>
Error encountered

2026-08-05T14:21:18.184Z SEVERE   Failed to connect to user: sys as sysdba
jdbc:oracle:thin:@//database:1521/ORCLPDB
ORA-01017: invalid credential or not authorized; logon denied

Cause: the SYS password was pasted into the interactive prompt rather than typed. Interactive password prompts in a terminal can silently mishandle pasted input (extra or missing characters, premature line breaks).
Fix: re-run the installer and type the password manually, character by character, instead of pasting it. On retry, the installation completed successfully:

Retrieving information.
The setting named: feature.fusabase was set to: true in configuration: default
The setting named: fusabase.secret.encKey was set to: ****** in configuration: default
Installing Oracle Backend for Firebase version 26.1.1-260430 in ORCLPDB
Completed installation for Oracle Backend for Firebase version 26.1.1-260430. Elapsed time: 00:00:05.801

8Enable the Schema for Fusabase

Now that the installer has created the OBAAS_ADMIN package, log in as the dedicated DBA user, not SYS, and run the enablement procedure:

docker exec -it database23 bash
sqlplus fb_admin@localhost:1521/ORCLPDB
BEGIN
  OBAAS_ADMIN.OBAAS_ENABLE_SCHEMA(
    'FUSABASE_USER',
    'BASE_PATH',
    'fusabase_user',
    FALSE
  );
END;
/
COMMIT;
Result PL/SQL procedure successfully completed.

Confirm the schema received the BAAS_ROLE:

SELECT granted_role FROM dba_role_privs WHERE grantee = 'FUSABASE_USER';
Result

GRANTED_ROLE
------------
RESOURCE
DBFS_ROLE
BAAS_ROLE

9Restart ORDS So the Console Tile Appears

Opening the ORDS landing page immediately after installation did not show an “Oracle Backend for Firebase” tile yet. ORDS loads its available Console tiles at process start, before the feature was enabled.

http://<host>:8282/ords/_/landing

Fix: restart the ORDS container. Safe, the configuration lives on the named volume, nothing is lost:

docker restart ords26
docker logs -f ords26   # watch until it's up, then Ctrl+C

Reload the landing page. The “Oracle Backend for Firebase” tile now appears.

10Sign In to the Console (and Fix “Invalid Credentials”)

Open the Console sign-in page. This may sit behind a reverse proxy or custom domain rather than the raw host:port. That’s fine, it’s the same ORDS instance:

https://<your-domain-or-host>/ords/baas-console

The sign-in form asks for three things:

  • Path (Advanced) — the ORDS schema mapping path/alias. Use fusabase_user.
  • Usernamefusabase_user
  • Password — the schema’s database password
Error encountered

Invalid credentials
If your ORDS schema alias is different from your username, you
can set it using the "Path" input in the "Advanced" options

Cause: Path and Username were both correctly set to fusabase_user, but the password entered in the browser didn’t match the one stored for the schema, most likely a typo or a special character (e.g. a trailing !) not being entered correctly.
Fix: reset the schema password directly in the database and sign in again with the new value:

docker exec -it database23 sqlplus / as sysdba
ALTER SESSION SET CONTAINER=ORCLPDB;
ALTER USER fusabase_user IDENTIFIED BY "<new_password>";

Then sign in again with Path fusabase_user, Username fusabase_user, and the new password. This confirmed the sign-in flow itself was correct, the only issue was the password value.

11Create Your First Project in the Console

With the sign-in issue resolved, the Console loads to an empty “Your projects” screen. This is the actual Oracle Backend for Firebase UI, running on top of the exact stack configured in Steps 1 through 10.

Oracle Backend for Firebase console showing empty Your Projects page with Create Project button
The Fusabase Console landing page. A project is a logical container/workspace for your applications.

Click Create project. Name it, then choose between manual setup and quickstart. Quickstart sets up Authentication and Storage for you automatically, both can be reconfigured later:

Create Project dialog in Oracle Backend for Firebase with quickstart authentication and storage options
Create Project dialog. Quickstart pre-enables authentication and storage so you can start building immediately.

The project appears on the dashboard tagged IN DEV, with 0 applications registered so far. This status maps directly to the schema you enabled with OBAAS_ENABLE_SCHEMA in Step 8:

Fusabase project dashboard showing newly created project marked IN DEV with 0 applications
Project created. Status IN DEV, 0 applications, owned by the FUSABASE_USER schema.

12Register a Flutter App and Install the SDK

Click into the project. The Overview page prompts you to add an application, with buttons for Web, Android, iOS, and Flutter. For this walkthrough, the target was a Flutter app talking to Oracle instead of Firebase:

Fusabase project overview page with buttons to add a Web, Android, iOS, or Flutter application
Project overview. Applications in project: 0. Choose a platform to register your first app.

Clicking Flutter opens a three-step wizard: Register application, Install SDK, Configure SDK. Step 1 just asks for an app nickname:

Add Oracle Backend for Firebase to your Flutter app wizard, step 1 register application with app nickname field
Step 1 of 3: Register application. Give your Flutter app a nickname.

Step 2 offers two ways to install the SDK. The ZIP option downloads the SDK and references it by local path in pubspec.yaml:

Install SDK step showing ZIP download option and pubspec.yaml dependency configuration for Fusabase Flutter SDK
Step 2, ZIP option: download the SDK, extract it into your project, then reference it in pubspec.yaml.

The GitHub option is simpler if you don’t want to vendor the SDK locally. It just adds a Git dependency:

dependencies:
  fusabase:
    git:
      url: https://github.com/oracle/fusabase-flutter-sdk.git
      ref: {version}
Install SDK step showing GitHub option with fusabase git dependency snippet for pubspec.yaml
Step 2, GitHub option: add fusabase as a Git dependency directly, no manual download needed.

13Configure the SDK with Real Dart Code

Step 3 generates ready-to-paste Dart code, already filled in with your actual project ID, app ID, storage bucket, and ORDS host. This is the part that saves the most time. Nothing here is a placeholder, it comes straight from the project you just created:

import 'package:fusabase/oracledb.dart';
import 'package:fusabase/core.dart';
import 'package:fusabase/auth.dart';
import 'package:fusabase/storage.dart';

Map<String, dynamic> options = {
    "schema": "fusabase_user",
    "app_name": "demoapp",
    "app_type": "DART",
    "app_id": "<your_app_id>",
    "objs_type": "dbfs",
    "project_id": "<your_project_id>",
    "storage_bucket": "<your_storage_bucket>",
    "auth_type": "base",
    "auth_id": "<your_auth_id>",
    "ords_host": "https://<your-ords-host>/ords/fusabase_user/"
};

FusabaseOptions fusabaseConfig = FusabaseOptions(options);

// initialize app
FusabaseApp fusabaseApp = Fusabase.initializeApp(options:fusabaseConfig);
// get database instance
final fusabaseDB = FusabaseOracledb.instance;
// get object store instance
final fusabaseStorage = FusabaseStorage.instance;
// get auth instance
final fusabaseAuth = FusabaseAuth.instance;

For Android specifically, the wizard also generates a manifest snippet for the OAuth callback activity. This has to go into AndroidManifest.xml or sign-in redirects silently fail:

<activity
    android:name="com.oracle.mobile.fusabase.flutter.FusabaseCallbackActivity"
    android:exported="true">
    <intent-filter android:label="fusabase_dart">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="baasmobile<app id in lowercase>" />
    </intent-filter>
</activity>
Configure SDK step showing generated Dart code with FusabaseOptions, app initialization, and AndroidManifest activity snippet
Step 3: Configure SDK. The console pre-fills your actual project_id, app_id, storage_bucket, and ords_host.
Worth noting
ords_host in this generated code points at /ords/fusabase_user/, the exact schema alias created back in Step 5 and enabled in Step 8. Everything from the low-level SQL work earlier in this post surfaces directly in this one config object.

14Understand Collections, Documents, and Security Rules

Before writing any app code, it’s worth opening the Database tab. Oracle Backend for Firebase does not use tables and rows. It stores data in documents organized into collections, the same mental model as Firestore:

Fusabase Database tab explaining collections, documents, fields, and sub-collections data model
Collections are containers for documents. Documents hold fields. Fields can vary between documents in the same collection.

By default, all data is private. The Security rules tab is where you decide who can read, write, update, or delete. The default rule blocks everything until you explicitly allow it:

match /{document=**} { allow read, write: if false; }
Fusabase Database security rules tab showing default deny-all rule and security rules sandbox for testing
Default security rule denies all read and write access. The sandbox panel on the right lets you simulate requests before publishing changes.

The sandbox panel on the right lets you simulate a request (Get, List, Create, and so on) against a specific document path, with or without authentication, before you commit to a rule change. That is worth using before opening anything up in a real project.

15Build and Run a Working Flutter Notes App

With the SDK wired in, the default Flutter counter demo runs first, just to confirm the toolchain and the Fusabase initialization code both work before writing real features:

Default Flutter Demo Home Page counter app running in Chrome at localhost after Fusabase SDK integration
Baseline check: the Flutter app builds and runs cleanly with the Fusabase SDK wired into main.dart.

From there, the actual feature work (a simple notes app backed by FusabaseOracledb and FusabaseAuth) went faster with an AI coding agent reading the SDK’s own source directly, rather than guessing at an API surface designed to resemble Firebase’s:

VS Code with Claude Code CLI agent reading the fusabase package source to summarize FusabaseAuth and FusabaseOracledb public methods
Pointing an AI agent at the installed fusabase package source in the pub cache to get exact method signatures, instead of assuming Firebase’s API matches.

The result: a notes screen that writes to a notes collection through fusabaseDB, with each document carrying the note text, a timestamp, and the creating user. Running on a real device:

Flutter notes app running on a mobile device showing a new note input field and an existing saved note
The finished Flutter app on a real device. A note typed here writes straight through Fusabase into the Oracle Database.

And the proof that it’s actually Oracle underneath, not a local mock: the same note appears as a live document in the Fusabase Console’s Database tab, under the notes collection, with text, created_at, and created_by fields exactly as written by the app:

Fusabase Database console showing the notes collection with a live document containing text, created_at, and created_by fields
The note from the mobile app, sitting in the notes collection inside the Oracle Database, visible in the Fusabase Console in real time.

That closes the loop: a self-hosted Oracle Database and ORDS stack, enabled for Fusabase through nothing but SQL*Plus and the ORDS CLI, now backing a real Flutter app with a Firebase-shaped SDK and zero third-party BaaS involved.

Full List of Errors Encountered (and Fixes)

Error Where Cause & Fix
ORA-03405: End of query reached; no additional text should follow. Multiple times, pasting multi-line SQL blocks into SQL*Plus Copy-paste of multiple statements at once confused SQL*Plus’s line buffer. Fix: run statements one at a time, or use a fresh sqlplus session per block.
ORA-65020: pluggable database ORCLPDB already closed Re-running ALTER PLUGGABLE DATABASE ... CLOSE Harmless. The PDB was already closed from a previous, successful command that got lost in the pasted block. Verify actual state with SELECT name, open_mode FROM v$pdbs; before assuming failure.
ORA-01543: tablespace 'FUSABASE_TBS' already exists CREATE TABLESPACE Object had already been created successfully in an earlier, visually confusing, pasted batch. Confirmed harmless via dba_tablespaces.
ORA-01920: user name 'FUSABASE_USER' conflicts with another user or role name CREATE USER Same cause as above, user already existed. Confirmed via dba_users.
bash: !@localhost: event not found Passing a password containing ! inline on the Bash command line Bash history expansion intercepts !. Fix: set +H, or better, omit the password from the command line and let sqlplus prompt for it interactively.
PLS-00201: identifier 'OBAAS_ADMIN.OBAAS_ENABLE_SCHEMA' must be declared Running OBAAS_ENABLE_SCHEMA before ords fusabase install The OBAAS_ADMIN package doesn’t exist until the ORDS-side installer has run. Fix: run ords --config <dir> fusabase install first.
ORA-01017: invalid credential or not authorized; logon denied ords fusabase install, SYS password prompt Password was pasted rather than typed into the interactive prompt, causing a mismatch. Fix: type the password manually.
Invalid credentials (Console sign-in page) Signing in to the Fusabase Console via /ords/baas-console Path and Username were correct, but the entered password didn’t match. Fix: reset it directly with ALTER USER fusabase_user IDENTIFIED BY "<new_password>"; and sign in again.

Final Credentials / Connection Summary

Role Username Used for
Console login / project owner fusabase_user Signing into the Fusabase Console, owns the created project
Schema-enablement admin fb_admin (DBA role) Running OBAAS_ENABLE_SCHEMA and similar administrative SQL
Database super-user sys as sysdba ORDS installer, COMPATIBLE/TDE/extended-strings setup
# ORDS landing page (shows the Console tile)
http://<your-host>:8282/ords/_/landing

# Fusabase Console direct sign-in (can sit behind a reverse proxy / custom domain)
https://<your-domain-or-host>/ords/baas-console
  Path:     fusabase_user
  Username: fusabase_user
  Password: <current schema password>

# Fusabase SDK connection (example for Flutter)
ords_host: http://<your-host>:8282/ords/fusabase_user/
schema: fusabase_user
Before going anywhere near production

  • Rotate every password used in this walkthrough: SYS, TDE keystore, fusabase_user, fb_admin.
  • Switch the ORDS standalone listener from HTTP to HTTPS.
  • Store the TDE keystore password and any generated Fusabase encryption passphrase in a proper secrets manager, not in a compose file or shell history.
Written up for oraclewithhassan.com, based on a real hands-on installation session against Oracle Backend for Firebase 26.1.1 on Oracle AI Database 23.26.1.0.0 and ORDS 26.1.2, followed by a working Flutter demo app built on top of it.

YOU MAY ALSO LIKE