Profile Inspector โ Firestore & Auth Diagnostic Tool โ
Last Updated: 2026-03-18
A unified inspection tool that queries Firebase Auth, users, adminProfiles, and merchantProfiles for a given UID and presents them side by side with automatic consistency checks.
Why this exists: Admin users have data spread across
users/{uid}andadminProfiles/{uid}(same UID, different collections). Fields likedisplayName,phone, andupdatedAtcan drift out of sync. This tool makes mismatches immediately visible.
Quick Start โ
# Full inspection โ Auth + users + adminProfiles + merchantProfiles
./tooling/scripts/inspect-profile.sh <USER_UID>
# Compare shared fields between users and adminProfiles
./tooling/scripts/inspect-profile.sh <USER_UID> --diff
# Raw JSON (pipe to jq, save to file, etc.)
./tooling/scripts/inspect-profile.sh <USER_UID> --json
# Inspect only one source
./tooling/scripts/inspect-profile.sh <USER_UID> --collection users
./tooling/scripts/inspect-profile.sh <USER_UID> --collection adminProfiles
./tooling/scripts/inspect-profile.sh <USER_UID> --collection auth
# Target a different project
./tooling/scripts/inspect-profile.sh <USER_UID> --project lantern-app-prodPrerequisites โ
- Node.js 22+
firebase-admininstalled (available in the repo's rootnode_modules)- Application Default Credentials for the target project, or
GOOGLE_CLOUD_PROJECTset in.env.local
What It Shows โ
Summary Header โ
A quick at-a-glance view:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PROFILE INSPECTOR โ aR7ivxIk48Wi... โ
โ Project: lantern-app-dev โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary:
UID: aR7ivxIk48Wijw1nXBs8C9KyfhB2
Role: admin
Auth record: โ
users doc: โ
adminProfiles: โ
merchantProfiles: โAutomatic Consistency Warnings โ
The script checks for common mismatches and flags them:
| Check | Example Warning |
|---|---|
Admin role but no adminProfiles doc | User has admin role but NO adminProfiles document |
adminProfiles exists but role โ admin | User has adminProfiles document but role is "user", not admin |
Merchant role but no merchantProfiles doc | User has merchant role but NO merchantProfiles document |
| Email mismatch (Auth vs Firestore) | Email mismatch: Auth=a@b.com, Firestore=x@y.com |
displayName mismatch (Auth vs users) | displayName mismatch: Auth="Foo", users="Bar" |
displayName mismatch (users vs adminProfiles) | displayName mismatch: users="Foo", adminProfiles="Bar" |
Collection Sections โ
Each source is printed with all fields, ordered alphabetically. Long encrypted/sensitive values are truncated with length indicators:
[encrypted]โ Client-side encrypted fields (e.g.,encryptedBirthDate,encryptedSeed)[sensitive]โ Key material or hashes (e.g.,salt,phoneSalt,authProofHash)
Diff Mode (--diff) โ
Compares the four shared fields between users and adminProfiles:
displayNamephonegithubUsernameupdatedAt
Flags mismatches with โ and shows both values. Also lists fields unique to each collection.
Options Reference โ
| Flag | Description |
|---|---|
--json | Output raw JSON instead of formatted table. Timestamps are ISO 8601. |
--diff | Show field-by-field comparison of users vs adminProfiles. |
--collection <name> | Only query one source: users, adminProfiles, merchantProfiles, or auth. |
--project <id> | Override Firebase project (default: lantern-app-dev). |
Collections Compared โ
users/{uid} โ
The main user profile document. Contains public fields (lanternName, interests, mood), encrypted personal data, encryption key material, auth method fields, role/ban state, and timestamps.
adminProfiles/{uid} โ
Supplementary document for admin users. Contains displayName (real name), phone (emergency contact), emergencyContact, notes, githubUsername, and admin password fields. Same UID as users.
merchantProfiles/{uid} โ
Supplementary document for merchant users. Created by Cloud Functions only. Read by merchants (own doc) and admins (all docs).
Firebase Auth Record โ
The authentication record: email, phone, providers, custom claims (role), disabled state, and login timestamps.
Common Workflows โ
"Is this admin fully set up?" โ
./tooling/scripts/inspect-profile.sh <UID>Check for:
Auth record: โandcustomClaims: {"role":"admin"}users doc: โwithrole: adminadminProfiles: โwithdisplayNamepopulated- No consistency warnings
"Why is displayName wrong in the admin portal?" โ
./tooling/scripts/inspect-profile.sh <UID> --diffThe admin portal reads from adminProfiles.displayName, while the main app may show users.displayName or Auth.displayName. The diff shows which one is stale.
"Quickly check encryption state" โ
./tooling/scripts/inspect-profile.sh <UID> --collection usersLook for salt or phoneSalt (which auth method), encryptionCanary, encryptedSeed, and recoveryBackupBlob.
"Export profile data for debugging" โ
./tooling/scripts/inspect-profile.sh <UID> --json > /tmp/profile-debug.jsonSee Also โ
- PHONE_AUTH_RESET.md โ Reset phone auth state for re-testing
- FIREBASE_EMULATOR_TESTING.md โ Local emulator testing
- LOCAL_TESTING.md โ General local dev testing
- Scripts Guide โ All available scripts