> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portalhq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# @portal-hq/firebase-storage

> Firebase Authentication storage adapter for Portal wallet backup and recovery on React Native.

The `@portal-hq/firebase-storage` package provides `FirebaseStorage`, a Portal [`Storage`](./core#backupoptions) adapter that stores and retrieves backup encryption material using **Firebase ID tokens**. Requests are made to Portal’s token backup service (TBS); the Portal **Client API key** and **Firebase ID token** are sent so the backend can authenticate your app and the signed-in Firebase user, consistent with native iOS and Android Firebase backup behavior.

## Installation

```bash theme={null}
npm install @portal-hq/firebase-storage
# or
yarn add @portal-hq/firebase-storage
```

You also need a configured Firebase project and a supported Firebase Auth integration (for example [`@react-native-firebase/auth`](https://rnfirebase.io/auth/usage)) so `getToken` can obtain ID tokens for the current user.

## The `FirebaseStorage` class

`FirebaseStorage` implements the Portal `Storage` contract from `@portal-hq/utils`. Portal injects its API client on the instance when you construct [`Portal`](./core#the-portal-class) (`adapter.api = portal.api`), which supplies the Client API key used in TBS requests.

### Class definition

```typescript theme={null}
export class FirebaseStorage implements Storage
```

### Constructor

```typescript theme={null}
constructor(opts: FirebaseStorageOptions)
```

### `FirebaseStorageOptions`

| Property   | Type                                                                | Required | Default                    | Description                                                                                                                                                                                                                                                               |
| ---------- | ------------------------------------------------------------------- | -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getToken` | `(options?: { forceRefresh?: boolean }) => Promise<string \| null>` | Yes      | -                          | Returns a Firebase **ID token** for the signed-in user, or `null` if there is no user. Should call your Auth SDK’s token API (for example `User#getIdToken`). When `options?.forceRefresh` is `true`, request a refreshed token (used internally after a `401` from TBS). |
| `tbsHost`  | `string`                                                            | No       | `'backup.web.portalhq.io'` | Hostname or URL for the token backup service. Trailing slashes are stripped; `localhost` uses `http`, otherwise `https` is assumed if no scheme is present.                                                                                                               |

```typescript theme={null}
import { FirebaseStorage } from '@portal-hq/firebase-storage'
import auth from '@react-native-firebase/auth'

const firebaseStorage = new FirebaseStorage({
  getToken: async (options?: { forceRefresh?: boolean }) => {
    const user = auth().currentUser

    if (!user) {
      return null
    }

    return user.getIdToken(Boolean(options?.forceRefresh))
  },
})
```

### The `getToken` callback

Portal invokes `getToken` before TBS traffic (including `validateOperations`). Implement it by delegating to Firebase Auth’s ID token API.

* **`options.forceRefresh`:** When `true`, obtain a new token from Firebase (for example `getIdToken(true)`). The adapter sets this on the retry path after an unauthorized (`401`) response so a stale token can be replaced.
* **Return `null`:** If there is no signed-in Firebase user, return `null`. Backup and recovery operations will fail until the user signs in and tokens are available.

Firebase **ID tokens** identify the end user to Portal’s backend for this backup method; they are sent as the `X-Firebase-Token` header together with the Portal Client API key (`Authorization: Bearer …` from the configured `IPortalApi`).

### When no Firebase user is signed in

If `getToken` resolves to `null`, `FirebaseStorage` throws standard `Error` instances, including:

* **`Firebase token is not available`** — Initial read/write/validate when no token could be obtained (for example no `currentUser`).
* **`Firebase token is not available. Ensure Firebase Auth is initialized and user is signed in.`** — From `validateOperations()` when the token is missing.
* **`Firebase token refresh failed`** — After a `401`, the adapter retries once with `getToken({ forceRefresh: true })`; if that still yields `null`, this message is thrown.

If the storage instance is not wired into `Portal`, you may also see **`Portal API not configured`** when `api` has not been set (normally Portal sets this for adapters listed under `backup`).

Other HTTP failures surface as messages such as **`Firebase account does not match this client`** (`403`), **`No encryption key found for Firebase backup method`** (`404`), **`TBS error <status>: …`**, or a **timeout** error if the request exceeds 30 seconds.

`delete()` is not supported for this method; calling it throws **`Firebase backups cannot be deleted`**.

***

## Portal integration

Pass the adapter on the `firebase` key of [`BackupOptions`](./core#backupoptions) and use [`BackupMethods.Firebase`](./core#backupmethods) with [`backupWallet`](./core#backupwallet) and [`recoverWallet`](./core#recoverwallet). For cloud-style Firebase backup, pass an empty ciphertext string for `recoverWallet`, matching other cloud backups in the React Native SDK.

```typescript theme={null}
import { BackupMethods, Portal } from '@portal-hq/core'
import { FirebaseStorage } from '@portal-hq/firebase-storage'
import auth from '@react-native-firebase/auth'

const firebaseStorage = new FirebaseStorage({
  getToken: async (options?: { forceRefresh?: boolean }) => {
    const user = auth().currentUser

    if (!user) {
      return null
    }

    return user.getIdToken(Boolean(options?.forceRefresh))
  },
})

const portal = new Portal({
  apiKey: 'YOUR_PORTAL_CLIENT_API_KEY',
  backup: {
    firebase: firebaseStorage,
  },
  gatewayConfig: 'https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY',
})
```

### Backup

```typescript theme={null}
const cipherText = await portal.backupWallet(BackupMethods.Firebase)
```

### Recovery

```typescript theme={null}
const addresses = await portal.recoverWallet('', BackupMethods.Firebase)
```

***

## Related documentation

* [@portal-hq/core](./core) — `Portal`, `BackupMethods`, `backupWallet`, `recoverWallet`, and `BackupOptions`
* [Back up a wallet — Firebase Auth backup](/sdks/react-native/guide/back-up-a-wallet#firebase-auth-backup) (product guide)
* [React Native Firebase — Authentication](https://rnfirebase.io/auth/usage)
