Skip to content

Support web, Android and iOS apps per profile - #20

Merged
smaranjit merged 3 commits into
mainfrom
feat/multi-app
Oct 6, 2026
Merged

smaranjit merged 3 commits into
mainfrom
feat/multi-app

Conversation

@smaranjit

@smaranjit smaranjit commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

What does this change?

Multiple apps per profile.

  • A profile now holds a list of the project's Firebase apps instead of one API key and App ID.
  • An App dropdown in the top bar picks the app whose key the UID -> ID Token, Custom -> ID Token and App Check tabs use.
  • Load apps imports every web, Android and iOS app through the Firebase Management API, using the service account. It fills in each app's App ID, API key, package name and SHA-1 (Android) or bundle ID (iOS). Running it again updates by App ID instead of duplicating.
  • Apps can also be added and edited by hand. Pasting an App ID sets the type to match.

API keys restricted to an app now work. An Android app's requests send X-Android-Package and X-Android-Cert, and an iOS app's send X-Ios-Bundle-Identifier, alongside the key, as the Firebase SDKs do. Before, only the key was sent, so Google rejected any key with an app restriction.

Persistence change:

  • App names, App IDs, package names, SHA-1s and bundle IDs are always saved.
  • Only API keys and debug tokens follow the checkbox, renamed remember API keys & debug tokens.
  • Existing profiles migrate into a single app on first launch.

Fixes found while testing:

  • Clear all claims failed with INVALID_CLAIMS : Not a JSON Object: null. It sent an empty customAttributes string, which the API now rejects; it now sends {}. This bug is in v0.1.6.
  • A refused Save on User Custom Claims no longer shows the previous "Saved." message beside the error.
  • Each tab now scrolls as a whole. Before, the last rows of a long decoded-claims table could fall below the window and couldn't be reached.
  • + New and Delete on profiles build profiles with a guaranteed app, so they no longer crash under the new data model.

Checklist

  • cargo fmt --all -- --check passes
  • cargo clippy --all-targets -- -D warnings passes
  • cargo test --all-targets passes: 42 tests, up from 19, also run on Rust 1.90 under Ubuntu 22.04
  • cargo build --release succeeds (Rust 1.90, --locked)
  • Tested manually against a Firebase project (a development one)
  • CHANGELOG.md updated under [Unreleased], if user-facing

Notes for the reviewer

Tested end to end in a sandboxed Ubuntu 22.04 desktop against the demo project, which has web, Android and iOS apps:

  • Upgrade from v0.1.6:
    • With remember on, the key, App ID and debug token carry over as one app.
    • With remember off, the profile starts with a blank web app.
  • Load apps:
    • Imports into a blank profile, or merges into an existing one.
    • A second run creates no duplicates.
  • Restricted keys:
    • The Android key, limited to dev.ftt.demo plus its SHA-1, returns an ID token. With the SHA-1 cleared it fails with Requests from this Android client application dev.ftt.demo are blocked.
    • The iOS key, limited to its bundle ID, returns an ID token.
    • Requests with the wrong package, SHA-1 or bundle ID, or none at all, were rejected when sent directly.
  • Persistence across restarts: with remember off, no keys or debug tokens are written, but every App ID, SHA-1 and bundle ID is.
  • Regression pass:
    • Every tab, the Users panel and lookups.
    • Custom claims: load, save, clear, and the over-limit case.
    • Profiles: new, rename, delete, and switching.
    • App Check, Copy and About.
    • The top bar at the 900×600 minimum window size.

Other notes:

  • ron is added as a dev-dependency for the migration tests. It's already in the tree through eframe's persistence feature.
  • The iOS plist values are read by plain string matching rather than an XML parser. Google generates these files in a fixed layout, and the comment in src/firebase/apps.rs explains why. Tests cover a real plist shape.
  • The guide's screenshots and GIF are refreshed for the new top bar.

@smaranjit smaranjit mentioned this pull request Oct 6, 2026
6 tasks done
Base automatically changed from docs/user-guide to main October 6, 2026 20:05
A profile now holds a list of the project's Firebase apps instead of one
API key and App ID, and an App dropdown in the top bar picks the one the
ID-token and App Check tabs use. Load apps imports every app in the
project, with its API key, package name and SHA-1 or bundle ID, through
the Firebase Management API; apps can also be added and edited by hand.

Requests made with an Android or iOS app's key now send X-Android-Package
and X-Android-Cert, or X-Ios-Bundle-Identifier, as the Firebase SDKs do,
so keys restricted to that app are accepted.

App names, IDs and platform identifiers are always saved; only API keys
and debug tokens follow the remember checkbox, renamed to "remember API
keys & debug tokens". Existing profiles migrate into a single app on first
launch.

The tab area now scrolls as a whole: with the taller top bar, the last
rows of a long claims table were left below the window.
Clear all claims sent an empty customAttributes string, which the
Identity Toolkit API now rejects with "INVALID_CLAIMS : Not a JSON
Object: null". Send "{}" instead, as the Admin SDKs do, and show a user
whose claims are "{}" as having none.

A Save refused before reaching the API (invalid JSON, over 1,000 bytes)
also left the previous "Saved." message on screen beside the error.
Covers Load apps, adding apps by hand, the identity headers sent for
Android and iOS keys, the renamed remember checkbox, and migration from
0.1.x. Screenshots and the quick-start recording are refreshed for the
new top bar.
@smaranjit
smaranjit merged commit 7817daa into main Oct 6, 2026
11 checks passed
@smaranjit
smaranjit deleted the feat/multi-app branch October 6, 2026 20:14
@smaranjit smaranjit mentioned this pull request Oct 6, 2026
6 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant