2026年8月4日火曜日

Oracle Backend for Firebaseを組み込んだアプリケーションをGoogleアカウントで認証する

Oracle Backend for Firebase(Fusabase)は、Google、Facebook、GitHubといったソーシャル・ログイン(Social login)および、外部IDプロバイダーによるログイン(OpenID Connect)をサポートしています。

本記事では、Fusabase SDKに含まれるAuthenticationモジュールをアプリケーションに組み込み、Social loginとして提供されているGoogleを構成して、アプリケーションのユーザー認証を行なってみます。


Authentication typeを構成することにより、外部のプロバイダーを使用したユーザー認証を実装することもできます。こちらの構成については、また別の機会に確認したいと思います。

注) Authentication typeにAdvancedを選択し、IDCSとしてOracle IAMを構成する場合、IAMの機能としてEnd-user self-registrationが必要です。Oracle IAMのIdentity Domain TypeがFreeだと、End-user self-registrationはサポートされていません(IAM Identity Domain Typesの表を参照)。そのため、Oracle Backend for Firebaseの組み込みの認証タイプ(BASIC)を変更し、AdvancedIDCSとしてOracle IAMを構成するには、有料のサブスクリプションが必要になります。

Googleによるユーザー認証を組み込むアプリケーションとして、以下のLiveLabsを実施して作成したアプリケーションを使用します。


Googleプロバイダを構成する



最初にリダイレクトURIを確認します。

Oracle Backend for Firebaseのコンソールにサインインし、AuthenticationSocial loginを開きます。

GoogleActionを実行します。


プロバイダをEnableに切り替えます。Enableにすると、リダイレクトURIが表示されます。なぜかCopy URIボタンが効かない(サイトをHTTPで構成しているからかもしれません)ため、表示されているリダイレクトURIを選択して、クリップボードにコピーします。

Client IdおよびClient Secretは、Googleに認証情報を作成することにより得られる値なので現時点では不明です。キャンセルをクリックし、ドロワーを閉じます。


Google Cloudのコンソールでの作業に移ります。

プロジェクトが作成されていることを前提とします。

APIとサービス認証情報を開きます。


認証情報の作成から、OAuthクライアントIDを選択します。


Google Auth Platformクライアントの作成に移ります。

アプリケーションの種類としてウェブアプリケーションを選択します。名前fusabaseとしました。

承認済みのリダイレクトURIとして、先ほどOracle Backend for Firebaseのコンソールで確認したリダイレクトURIを設定します。

以上で作成します。


OAuthクライアントが作成されます。クライアントIDクライアントシークレットが表示されるので、これらをコピーします。JSONをダウンロードしておくのも良いでしょう。

OKをクリックしてダイアログを閉じます。


OAuthクライアントとしてfusabaseが作成されます。


Oracle Backend for Firebaseのコンソールに戻り、Authenticationを開きます。

Social loginGoogleの設定を更新します。Googleに作成したOAuthクライアントfusabaseのクライアントIDクライアントシークレットを設定します。

プロバイダーをEnableにし、Saveします。


以上で、Googleアカウントによるソーシャル・ログインが有効になりました。


Web/JavaScriptアプリケーションを認証する



JavaScript SDKのAuthenticationモジュールの説明は、以下に記載されています。

LiveLabsのBuild a Recipe Web App with Oracle Backend for Firebaseを実施して作成されたアプリケーションを元に作業します。

Sign inボタンをクリックすると表示されるパネルのSign inCreate accountの間に、Sign in with Googleというボタンを追加します。


index.htmlsignInButtonの下に、以下の一行を挿入します。ページに表示されるボタンとして、Sign in with Googleが追加されます。

<button id="signInWithGoogleButton" class="btn btn-outline" type="button">Sign in with Google</button>


scripts/app.jsの先頭にあるimport文を更新します。fusabase/authより追加で、GoogleAuthProvidersignInWithPopupをインポートします。
import {
  GoogleAuthProvider,
  signInWithPopup,
  createUserWithEmailAndPassword,
  getAuth,
  onAuthStateChanged,
  signInWithEmailAndPassword,
  signOut
} from "fusabase/auth";
ボタンsignInWithGoogleを、オブジェクトelの属性として含めます。

signInButtonの下に、以下の一行を挿入します。

signInWithGoogleButton: document.querySelector("#signInWithGoogleButton"),


ボタンsignInWithGoogleButtonをクリックしたときに実行されるコードを追加します。見つけやすいように、signInButtonのイベントリスナー定義の下の配置します。
  el.signInWithGoogleButton.addEventListener("click", () => {
    runAction("Signed in with Google.", async () => {
      // ── Sign in with Google ─────────
      await signInWithPopup(auth, new GoogleAuthProvider());
    });
  });

以上でアプリケーションの更新は完了です。

RecipeShareのアプリケーションにアクセスし、Sign In with Googleを実行します。


Googleでログインの画面がポップアップします。ログインするGoogleアカウントを選択します。


アプリケーション名として表示されているRecipeShareは、Google Auth Platformブランディングで設定しています。


Googleアカウントでのサインインに成功すると、メール・アドレスが表示されます。


以上で、Web/JavaScriptアプリケーションを、Googleアカウントで認証することができました。


iOS/Swiftアプリケーションを認証する



iOS SDKのAuthenticationモジュールの説明は、以下に記載されています。

LiveLabsのBuild a Recipe iOS App with Oracle Backend for Firebaseを実施して作成されたアプリケーションを元に作業します。

Services/AuthService.swiftに、GoogleアカウントでサインインするファンクションsignInWithGoogleを追加します。ファンクションsignInの下に配置します。
    /// Sign in with Google
    func signInWithGoogle() async throws {
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }

        do {
            _ = try await FusabaseAuth.auth().signIn(with: GoogleAuthProvider())
        } catch {
            errorMessage = error.localizedDescription
            throw error
        }
    }

Views/AuthView.swiftに、追加したファンクションsignInWithGoogleを呼び出すボタンSign In With Googleを追加します。

AuthView.swiftの末尾に、アクションとしてsignInWithGoogleを追加します。
    // MARK: - Actions

    private func signInWithGoogle() {
        Task {
            do {
                try await authService.signInWithGoogle()
            } catch {
                // AuthService surfaces the message via `errorMessage`; nothing else to do.
            }
        }
    }

アクションsignInWithGoogleを呼び出すボタンを追加します。sign-upとsign-inを切り替えるボタン(表示はリンク)の下に配置します。
            // Sign In With Google
            Button(action: signInWithGoogle) {
                HStack {
                    if authService.isLoading {
                        ProgressView()
                            .controlSize(.small)
                            .padding(.trailing, 4)
                    }
                    Text("Sign In with Google")
                        .fontWeight(.semibold)
                        .frame(maxWidth: .infinity)
                }
            }
            .buttonStyle(.borderedProminent)
            .controlSize(.large)
            .disabled(authService.isLoading)

以上でアプリケーションの更新は完了です。

RecipeShareのアプリケーションを実行します。Sign In with Googleのボタンが追加されています。

Sign In with Googleをクリックします。


Googleでログインの画面が表示されます。Googleアカウントを入力し、Enterを送信します。


Googleアカウントの構成によると思いますが、色々な方法で本人確認を求められます。


RecipeShareに再ログインしようとしています。と表示されたので次へ進みます。


Googleアカウントのサインインに成功し、登録されているレシピの一覧が表示されます。


以上で、iOS/Swiftアプリケーションを、Googleアカウントで認証することができました。


Android/Javaアプリケーションを認証する



Android SDKのAuthenticationモジュールの説明は、以下に記載されています。

LiveLabsのTitle Build a Recipe Android App with Oracle Backend for Firebaseを実施して作成されたアプリケーションを元に作業します。

Fusabase Android SDKの説明には記載されていませんが、Fusabase Android SDKのAuthenticationモジュールには、startActivityForSignInWithProviderが含まれています。このメソッドを使って、Googleアカウントによるサインインを実装します。

掲載しているほとんどのコードは、Claude Opus 5に生成させています。

AuthRepository.javaに以下の2つのファンクションを追加します。
    /**
     * Signs in with Google. The SDK opens a Custom Tab for the OAuth flow, so an
     * Activity is required. The result arrives through the auth state listener
     * once the browser redirects back to SocialLoginActivity.
     */
    public void signInWithGoogle(Activity activity) {
        isLoading.setValue(true);
        errorMessage.setValue(null);
        auth.startActivityForSignInWithProvider(activity, new GoogleAuthProvider(auth))
                .addOnSuccessListener(result -> isLoading.postValue(false))
                .addOnFailureListener(error -> {
                    isLoading.postValue(false);
                    errorMessage.postValue(error.getMessage());
                });
    }

    public void resumePendingSocialLogin() {
        Task<AuthResult> pending = auth.getPendingAuthResult();
        if (pending == null) {
            isLoading.postValue(false);
            return;
        }
        pending.addOnSuccessListener(result -> isLoading.postValue(false))
                .addOnFailureListener(error -> {
                    isLoading.postValue(false);
                    errorMessage.postValue(error.getMessage());
                });
    }

これらのファンクションが使用しているクラスをインポートするように、ファイルの先頭に以下のインポート文を追加します。
/* Sign in with Google */
import android.app.Activity;
import com.oracle.mobile.fusabase.auth.GoogleAuthProvider;
import com.oracle.mobile.fusabase.task.Task;
import com.oracle.mobile.fusabase.auth.AuthResult;

本家のFirebase Authentication SDKでは、startActivityForSignInWithProvider() は主に OAuthProvider(Apple、GitHub、Microsoft、OIDC など)の認証で使用するAPIとして紹介されています。Googleアカウントによるサインインについては、現在のFirebase公式ドキュメントでは Credential Manager を使用する方法が推奨されています。

Oracle Backend for Firebase (Fusabase) は、Oracle Databaseのクライアント・アプリケーションを作成する際に、Firebaseの開発体験を提供するSDKです。作成するアプリケーションは、あくまでOracle Databaseのクライアント・アプリケーションなので、ユーザー認証もエンタープライズ向けのOpenID Connectによる認証が主になるでしょう。そのため、Googleアカウントによる認証もCredential Managerを使わずに実装しました。

サインインの画面にボタンSign in with Googleを追加します。

res/values/strings.xmlに以下の1行を挿入します。ボタンのラベルとなる文字列です。

<string name="auth_button_google">Sign in with Google</string>


サインインの画面にボタンSign in with Googleを追加します。

res/layout/fragment_auth.xmlを開き、以下の要素をボタンSign inの下に配置します。
        <com.google.android.material.button.MaterialButton
            android:id="@+id/googleButton"
            style="@style/Widget.Material3.Button.OutlinedButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/spacing_sm"
            android:text="@string/auth_button_google" />

AuthFragment.javaを開き、ボタンのアクション(クリック)とAuthRepository.javaに記載したファンクションの紐付けを行います。

ボタンSign in with Google(googleButton)をクリックしたときに、ファンクションsignInWithGoogleが呼び出されるように、以下のコードを追加します。
        binding.googleButton.setOnClickListener(v -> {
            binding.errorText.setVisibility(View.GONE);
            App.get().auth().signInWithGoogle(requireActivity());
        });
他のボタンと同様に、ページのロード中はクリックを無効にします。以下の1行を、App.get().auth().getIsLoading().observe内に含めます。

binding.googleButton.setEnabled(!active);


resumePendingSocialLoginを呼び出すコードを、AuthFragment.javaの末尾に追加します。
    @Override
    public void onResume() {
        super.onResume();
        App.get().auth().resumePendingSocialLogin();
    }

main/AndroidManifest.xmlに記載されているSocialLoginActivityの設定を更新します。

android:launchMode="singleTop"を追加し、android:schemeとして、baasmobileで始まるapp_id(英子文字)を文字列として与えます。以下はandroid:schemeの例です。app_idは、作成したアプリケーションごとに異なります。

baasmobile581fb7467326f5b9e063020012ac0157
        <activity
            android:name="com.oracle.mobile.fusabase.auth.SocialLoginActivity"
            android:exported="true"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="baasmobile581fb7467326f5b9e063020012ac0157" />
            </intent-filter>
        </activity>


Googleアカウントによるユーザー認証の実装については以上で完了です。

Androidシミュレータを使って動作確認をするにあたって、ords_hostに10.0.2.2として仮想ネットワークを設定していると、Googleアカウントによるユーザー認証ができません。コールバック・アドレスはHTTPSで保護されているかlocalhostである必要があります。

そのため、main/fusabase-config.jsonords_hostでのホスト指定を、10.0.2.2からlocalhostに戻します。


AndroidシミュレータからORDSに直接接続する代わりに、adb - Android Debug Bridgeを使ってホスト上のTCPポート8181を、シミュレータから見たlocalhost:8181に割り当てます。

~/Library/Android/sdk/platform-tools/adb reverse tcp:8181 tcp:8181
~/Library/Android/sdk/platform-tools/adb reverse --list

adbへのパスは、Android Studioをインストールした環境によって、異なる可能性があります。

% ~/Library/Android/sdk/platform-tools/adb reverse tcp:8181 tcp:8181

% ~/Library/Android/sdk/platform-tools/adb reverse --list

host-10 tcp:8181 tcp:8181


% 


以上で、すべての設定が完了しました。

RecipeShareのアプリケーションを実行します。Sign in with Googleのボタンが追加されています。

Sign in with Googleをクリックします。


アカウントの選択画面に移ります。すでにサインインしたことのあるアカウントを選択するか、Use another accountを選択して、新たにサインインするユーザーを指定します。


アカウントの設定に応じた本人確認の手順が要求されます。

最終的にGoogleアカウントによる認証が成功すると、登録されているレシピの一覧が表示されます。


以上で、Android/Javaアプリケーションを、Googleアカウントで認証することができました。

2026年7月28日火曜日

Oracle Backend for FirebaseのCLIインターフェースfusabase-cliを使用する

これまでの記事では、Oracle Backend for Firebaseの操作をGUIで実施してきました。Oracle CorporationではGUIの操作をコマンドラインから実施できるように、CLIのツールとしてfusabase-cliを提供しています。このツールはGitHubで公開されています。

Oracle® Backend for Firebase (Fusabase) CLI
https://github.com/oracle/fusabase-cli

本記事ではfusabase-cliを利用して、前回の記事「Oracle Backend for FirebaseのLiveLabsを実施する」で実施しているGUIによる作業を、CLIによる作業に置き換えてみます。

CLIの構成手順については、公式ドキュメントにも記載があります。

Oracle Backend for Firebase, Release 26.1
Developer's Guide

公式ドキュメントに記述されている、fusabase-cliをインストールするコマンドは以下になります。

npm i -g fusabase-cli

残念なことに、-gオプションをつけてfusabase-cliをグローバル・インストールすると、fusabase-cliを実行するディレクトリに配置するfusabase.config.jsを読み込みません。これは、現状のfusabase-cliがfusabase.config.jsを検索するディレクトリを、fusabase-cliがインストールされているディレクトリから遡って探すようになっているためです。

GitHubのページに記載されているように、fusabase-cliのリポジトリをクローンしてインストールするか、または、-gオプションを外してインストールすると、作業ディレクトリに配置しているfusabase.config.jsが読み込まれます。

本記事ではfusabase-cliをローカル・インストールして、"npx fusabase"のエイリアスとしてfusabaseを登録することで、fusabase-cliを使用します。

fusabase-cliのインストール手順は以下になります。

作業ディレクトリとしてfusabase-livelabsを使用します。

cd fusabase-livelabs

Documents % cd fusabase-livelabs 

fusabase-livelabs % 


npm install fusabase-cli

fusabase-livelabs % npm install fusabase-cli


up to date, audited 116 packages in 954ms


15 packages are looking for funding

  run `npm fund` for details


10 high severity vulnerabilities


Some issues need review, and may require choosing

a different dependency.


Run `npm audit` for details.

fusabase-livelabs % 


エイリアスを設定します。

alias fusabase="npx fusabase"

fusabase-livelabs % alias fusabase="npx fusabase"

fusabase-livelabs % 


npx実行時にnoticeレベルのログが表示されないように、デフォルトをwarnに変更します。
その後に、インストールされたfusabaseのバージョンを確認します。

npm config set loglevel warn
fusabase --version

fusabase-livelabs % npm config set loglevel warn

fusabase-livelabs % fusabase --version          

26.1.1

fusabase-livelabs % 


aliasの設定は、.bashrcや.zshrcなどに記載すると永続化できます。


OAuthクライアントを作成する



fusabase-cliは認証のために、OBAAS_ADMIN.ENABLE_SCHEMAを実行してOracle Backend for Firebaseを有効にしたスキーマに作成した、OAuthクライアントのクライアントIDとクライアント・シークレットを使用します。

OAuthクライアントの作成手順は、公式ドキュメントの3.8.2 Create an OAuth Client for the CLIで紹介されています。

公式ドキュメントにそった手順により、OAuthクライアントを作成できることは確認しました。その手順をそのまま転記してもしかたがないので、パッケージORDS_SECURITYを使って、OAuthクライアントを作成するスクリプトを記述してみました。


Oracle Backend for Firebaseが有効化されたスキーマに接続し、上記のスクリプトを実行してOAuthクライアントを作成します。クライアントIDとクライアント・シークレットが印刷されるので、それを取得します。

sql testuser@localhost/freepdb1
@create_oauth_client

fusabase-livelabs % sql testuser@localhost/freepdb1


SQLcl: 火 7月 28 13:40:57 2026のリリース26.1 Production


Copyright (c) 1982, 2026, Oracle.  All rights reserved.


パスワード (**********?) *******

接続先:

Oracle AI Database 26ai Free Release 23.26.2.0.0 - Develop, Learn, and Run for Free

Version 23.26.2.0.0


SQL> @create_oauth_client

OAuth client fusabase-cli is deleted.

OAuth client fusabase-cli is created.

client_id: 8gqfzPOwliW5LCyqGk8ofA..

client_secret: 7fijW5RzBki7jlW66CmLNQ..

Role SQL Developer has granted to OAuth user fusabase-cli.



PL/SQLプロシージャが正常に完了しました。


Oracle AI Database 26ai Free Release 23.26.2.0.0 - Develop, Learn, and Run for Free

Version 23.26.2.0.0から切断されました

fusabase-livelabs % 


印刷されたclient_idとclient_secretの値は、fusabase-cliの初期化時に使用します。


CLIよりサインインする



作業ディレクトリにfusabase.config.jsとして、Oracle Backend for Firebaseへ接続するURLを設定します。
module.exports = {
  host: 'http://localhost:8181/ords/testuser/'
}
fusabase-cliでサインインします。

fusabase init

先ほど取得したクライアントIDとクライアント・シークレットを入力します。

fusabase-livelabs % fusabase init

Type ORDS clientId (with SQL Developer Role) · 8gqfzPOwliW5LCyqGk8ofA..

Type ORDS clientSecret · 7fijW5RzBki7jlW66CmLNQ..

http://localhost:8181/ords/testuser/

Logged In successfully!

Here are the projects accessible: 

Type (or choose) ProjectId to work on: · 573E3A97FC7320ADE063020012AC296D => recipe-workshop

Using project: 573E3A97FC7320ADE063020012AC296D

fusabase-livelabs % 


Logged In successfully!と表示されれば、Oracle Backend for Firebaseのサーバーにサインインできています。

サインインに成功すると.fusabase.confファイルに、アクセス・トークンやプロジェクトIDが記載されます。fusabase-cliはこのファイルからアクセス・トークンやその他の情報を参照します。アクセス・トークンの有効期限は、OAuthクライアントの作成時に実行したスクリプトcreate_oauth_client.sqlの中の、定数C_TOKEN_DURATIONに設定しています。

トークンの有効期限が過ぎた時は、fusabase init(またはfusabase login)を再実行する必要があります。クライアントIDやクライアント・シークレットを覚えていれば、再度、create_oauth_client.sqlを実行する必要はありません。

以上で、fusabase-cliが利用可能になりました。


セキュリティ・ルールを設定する



fusabase-cliでセキュリティ・ルールを設定します。制限なしでアクセスするルールをallow-all.txtとして、ファイルに記載します。


このセキュリティ・ルールをDatabaseに適用するために、以下のコマンドを実行します。

fusabase cel add --path=allow-all.txt

Rule Added Successfullyと表示されると、--pathで指定したセキュリティ・ルールが適用され、PUBLISHEDの状態になります。

fusabase-livelabs % fusabase cel add --path=allow-all.txt


match /{document=**} { allow read, write: if true;}


Rule Added Successfully!!

fusabase-livelabs % 


セキュリティ・リストの確認にはlistコマンドを使用します。

fusabase cel list

最終行のPUBLISHEDが1のセキュリティ・ルールが、現在適用されているセキュリティ・ルールになります。

fusabase-livelabs % fusabase cel list

Fetched Successfully:

  RULE                                                                                              PUBLISH 

  match /{document=**} { allow read, write: if true;}                                               0       

  match /recipes/{recipeId} {                                                                       0       

    allow read: if true;                                                                                    

    allow create: if request.auth != null && request.resource.data.ownerId == request.auth.uid;             

    allow update: if request.auth != null && request.auth.uid == resource.data.ownerId;                     

  }                                                                                                         

  match /recipes/{recipeId}/ratings/{ratingId} {                                                            

    allow read: if true;                                                                                    

    allow create: if request.auth != null;                                                                  

  }                                                                                                         

  match /{document=**} { allow read, write: if true;}                                               0       

  match /{document=**} { allow read, write, create: if true;}                                       0       

  match /{document=**} { allow read, write: if true;}                                               0       

  match /recipes/{recipeId} {                                                                       0       

      allow read: if request.auth != null;                                                                  

      allow create: if request.auth != null && request.resource.data.ownerId == request.auth.uid;           

      allow update: if request.auth != null && request.auth.uid == resource.data.ownerId;                   

  }                                                                                                         

  match /recipes/{recipeId}/ratings/{ratingId} {                                                            

      allow read: if request.auth != null;                                                                  

      allow create: if request.auth != null;                                                                

  }                                                                                                         

  match /{document=**} { allow read, write: if true;}                                               0



[中略]


  match /recipes/{recipeId} {                                                                       0       

      allow read: if request.auth != null;                                                                  

      allow create: if request.auth != null && request.resource.data.ownerId == request.auth.uid;           

      allow update: if request.auth != null && request.auth.uid == resource.data.ownerId;                   

  }                                                                                                         

  match /recipes/{recipeId}/ratings/{ratingId} {                                                            

      allow read: if request.auth != null;                                                                  

      allow create: if request.auth != null;                                                                

  }                                                                                                         

                                                                                                            

  match /{document=**} { allow read, write: if true;}                                               0       

                                                                                                            

  match /{document=**} { allow read, write: if true;}                                               1       

                                                                                                            

fusabase-livelabs %        


listコマンドでは、すべての変更履歴が一覧されます。現行のfusabase-cliでは、表示する行数を制限したりPUBLISHEDの行だけを表示するといったオプションを見つけることはできませんでした。

レシピの更新を作成者に限定するセキュリティ・ルールは以下です。

Web向けです。

iOSおよびAndroid向けです。

このセキュリティ・ルールを適用するfusabase-cliのコマンドは以下になります。

fusabase cel add --path=database-rules.txt

fusabase-livelabs % fusabase cel add --path=database-rules.txt

match /recipes/{recipeId} {

    allow read: if request.auth != null;

    allow create: if request.auth != null && request.resource.data.ownerId == request.auth.uid;

    allow update: if request.auth != null && request.auth.uid == resource.data.ownerId;

}

match /recipes/{recipeId}/ratings/{ratingId} {

    allow read: if request.auth != null;

    allow create: if request.auth != null;

}


Rule Added Successfully!!

fusabase-livelabs % 


Databaseのセキュリティ・ルールはfusabase-cliで設定できますが、現行のfusabase-cliでは、Storageのセキュリティ・ルールは操作できません。

ワークアラウンドとして、Storageのセキュリティ・ルールを設定するスクリプトを書きました。


(注:現行のfusabase-cliはスクリプト内のstorage=2の部分が1としてハード・コードされているため、Databaseのセキュリティ・ルールの操作に固定されています。)

Storageのセキュリティ・ルールとして制限なしを設定する場合、以下のコマンドを実行します。

sh update-security-rules.sh allow-all.txt

fusabase-livelabs % sh update-security-rules.sh allow-all.txt 

fusabase-livelabs %


Storageのセキュリティ・ルールを一覧するスクリプトは以下です。


sh list-security-rules.sh

fusabase-livelabs % sh list-security-rules.sh 

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100  4490    0  4490    0     0   140k      0 --:--:-- --:--:-- --:--:--  141k

"rule","created_at","publish"

"match /{document=**} { allow read, write: if true;}","2026-07-23 02:04:15.541576",0

"match /recipes/{recipeId}/{fileName} {

  allow read: if true;

  allow create: if request.auth != null;

}","2026-07-23 03:22:07.450843",0

"match /{document=**} { allow read, write: if true;}","2026-07-23 04:03:41.637378",0

"match /recipes/{recipeId}/{fileName} {

    allow read: if true;

    allow create: if request.auth != null;

}","2026-07-23 07:44:59.371574",0

"match /{document=**} { allow read, write: if true;}","2026-07-23 08:01:50.348963",0

"match /recipes/{recipeId}/{fileName} {

    allow read: if true;

    allow create: if request.auth != null;

}","2026-07-23 19:54:31.101444",0


[中略]


"match /{document=**} { allow read, write: if true;}

","2026-07-28 02:18:58.799914",0

"match /recipes/{recipeId}/{fileName} {

    allow read: if true;

    allow create: if request.auth != null;

}

","2026-07-28 02:19:58.819528",0

"match /{document=**} { allow read, write: if true;}

","2026-07-28 05:20:25.188484",1

fusabase-livelabs % 


認証済みのユーザーのみ、写真をアップロードできるようにするStorageのセキュリティ・ルールは以下です。


このセキュリティ・ルールは、以下のコマンドで設定します。

sh update-security-rules.sh storage-rules.txt

fusabase-livelabs % sh update-security-rules.sh storage-rules.txt 

fusabase-livelabs % 




Webアプリを実装する



fusabase-cliでWebアプリを作成します。application createコマンドを実行します。

fusabase application create

Application NameとApplication Typeの入力を求められます。

fusabase-livelabs % fusabase application create

Provide Application Name:  · RecipeShareWeb

Select Application Type:  · web

Application Created Successfully!!

{"APP_ID":"57A620B87BE604F8E063020012AC8D05"}

fusabase-livelabs % 


作成したアプリケーションは、application listコマンドで一覧できます。

fusabase application list

fusabase-livelabs % fusabase application list

Fetched Successfully :

  Project ID                         App ID                             App Name                          App Type   Active 

  573E3A97FC7320ADE063020012AC296D   578E20ADE7B7710BE063020012AC935F   RecipeShare                       IOS        1      

  573E3A97FC7320ADE063020012AC296D   57A620B87BE604F8E063020012AC8D05   RecipeShareWeb                    web        1      

  573E3A97FC7320ADE063020012AC296D   578F1539F98EA50AE063020012AC11EF   com.oracle.fusabase.recipeshare   ANDROID    1      

fusabase-livelabs % 


アプリケーションの削除はapplication deleteコマンドで行います。削除対象のApp IDを指定します。

fusabase application delete --appid=57A620B87BE604F8E063020012AC8D05

fusabase-livelabs % fusabase application delete --appid=57A620B87BE604F8E063020012AC8D05

Successfully deleted the application

fusabase-livelabs %


あらかじめ、アプリケーション名とタイプを記載したJSONファイルを用意することで、対話せずにアプリケーションの作成ができます。

以下の内容のファイルをapp.jsonとして用意します。

{ "APP_NAME": "RecipeShareWeb", "APP_TYPE": "web" }

fusabase application create --path=app.json

fusabase-livelabs % fusabase application create --path=app.json

Application Created Successfully!!

{"APP_ID":"57A620B87BE704F8E063020012AC8D05"}

fusabase-livelabs % 


作成したアプリケーションの構成データは、application getコマンドで取得します。application listコマンドよりApp IDを確認しておきます。

fusabase application get --appid=<App Id>

ords_hostはnullになっています。この値はfusabase.config.jsにhostとして設定した値になります。

fusabase-livelabs % fusabase application get --appid=57A620B87BE704F8E063020012AC8D05

Response data:

{

  "schema": "testuser",

  "app_name": "RecipeShareWeb",

  "app_type": "web",

  "app_id": "57A620B87BE704F8E063020012AC8D05",

  "objs_type": "dbfs",

  "project_id": "573E3A97FC7320ADE063020012AC296D",

  "storage_bucket": "dbfs_CXJHFAIIZAPLDEH",

  "auth_type": "base",

  "auth_id": "573E3A97FC7720ADE063020012AC296D",

  "ords_host": null

}

fusabase-livelabs % 


以上で、CLIでアプリケーションの作成ができました。

ただし、なぜかCLIで作成したアプリケーションはWebのコンソールから参照できません。CLIのapplication listの一覧には含まれますが、注意が必要でしょう。




Backendを初期化する



LiveLabsのアプリケーションから作成したユーザーは、fusabase auth listでは一覧されないようです。

fusabase auth list

fusabase-livelabs % fusabase auth list

Successfully fetched service details

auth type:base

Fetched Successfully!!

  First Name   Last Name   Email   UUID   Provider   Verified   Active   Ctime 

fusabase-livelabs % 


CLIから作成したユーザー(auth addで作成したユーザー)は、auth listで一覧されます。

ワークアラウンドとして、プロジェクトに作成されているユーザーを一覧するスクリプトを書きました。


このスクリプトを実行します。

sh list-users.sh

fusabase-livelabs % sh list-users.sh 

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100   394    0   394    0     0  11455      0 --:--:-- --:--:-- --:--:-- 11588

"first_name","last_name","username","email","uuid","provider","display_name","verified","active","creationTime","lastSigninTime"

"-","-","test@example.com","test@example.com","57A67E98FC627120E063020012ACF888","UserNamePassword","- -","false","true","2026-07-28T06:07:35.897414Z","2026-07-28T06:18:34.300295Z"

fusabase-livelabs % 


作成したユーザーのusernameを見つけ、削除します。

fusabase auth delete --username=test@example.com

fusabase-livelabs % fusabase auth delete --username=test@example.com

Successfully fetched service details

auth type:base

Successfully deleted app user

fusabase-livelabs % 


Databaseのコレクションrecipesを削除します。

作成されているコレクションを確認します。database listコマンドを実行します。

fusabase database list root

fusabase-livelabs % fusabase database list root

Response data:

  Collection Name   Collection_Id 

  emp               3440030340    

  recipes           3905671794    

fusabase-livelabs % 


コレクションrecipesを削除します。確認がなく、コマンドを実行したら即削除されるので、実行には細心の注意が必要です。

fusabase database delete recipes

fusabase-livelabs % fusabase database delete recipes

Path is : recipes

Collection delete Successfully:

{"message":"success"}

fusabase-livelabs %


コレクションrecipesが削除されたことを確認します。

fusabase database list root

fusabase-livelabs % fusabase database list root

Response data:

  Collection Name   Collection_Id 

  emp               3440030340    

fusabase-livelabs % 


Storageに作成されているフォルダrecipesを削除します。

Storageは作成済みのフォルダについて、storage listコマンドで内容や存在を確認できます。

fusabase storage list recipes

fusabase-livelabs % fusabase storage list recipes

Successfully fetched service details

storage type :dbfs

List of Files:

  ----File Name---- 

List of Directories:

  ----Directory Name----                    

  /recipes/57A67E98FC6B7120E063020012ACF888 

fusabase-livelabs % 


しかし、Databaseのようにrootという指定が効かないため、ルート・フォルダ直下をリストする方法を見つけることができませんでした。

削除についてはstorage delコマンドで実行できます。このコマンドも確認がなく、コマンドを実行したら即削除されます。

fusabase storage del recipes

fusabase-livelabs % fusabase storage del recipes

Successfully fetched service details

storage type :dbfs

Successfully deleted file from storage

fusabase-livelabs % 


以上で、Oracle Backend for FirebaseのLiveLabsで、GUIのコンソールから実施していた作業を、すべてfusabase-cliおよび、一部ワークアラウンドのスクリプトを使って、CLIで実行することができました。

今回の記事は以上になります。