| Name | Phone | Tier | Group | Last active |
|---|
These buttons grant the Wasl Pro entitlement (Daily features only — Quran, prayer times, streak). To unlock Umrah features (live map, AI Planner, Bills, Hotel, Lost Pilgrim, Group Du'as), use the Pilgrim Pass buttons below.
Pilgrim Pass unlocks the Umrah/Hajj feature set. Stacks on existing time (re-granting adds to remaining days).
Permanently deletes the user from Firebase Auth, Firestore, and clears their group references and RTDB heartbeats. Cannot be undone.
| Name | Code | Members | Accommodation | Created |
|---|
| Name | Phone | Tier | Role |
|---|
Broadcast push
Send a notification now, or schedule it for a future time (optionally repeating daily / weekly). Audience size is reported after dispatch.
Scheduled
Broadcasts queued for a future time. Cancel any here before they fire.
| When | Title | Audience | Recurring |
|---|
Recent broadcasts
History of everything sent — both immediate "Send now" and previously-scheduled broadcasts. Newest first. Last 50.
| When | Source | Title | Audience | Status | Delivered |
|---|
| When | Triggered by | Group | Trigger | Battery | Location | Hotel |
|---|
| Pri | Category | Title | User | Status | Age | Src |
|---|
Log a ticket on user's behalf
Use this when a user reported an issue outside the app (WhatsApp, email, in person).
| Name | Phone | Tier | Last active |
|---|
—
—
Audit-logged. Use these to fix the underlying issue.
Audit-logged. Add a note after using these so the next admin knows why.
Publish the initial 10 spiritual places (5 Makkah, 5 Madinah) with
stories, du'as and source citations. Idempotent — safe to re-run
after editing ziyarat-seed.json to push updates.
Mobile clients pick up new content within 6 hours, or instantly
on pull-to-refresh.
Seed the pre-authored "Test your understanding" question pools (multiple-choice, ~5 per ayah) into Firestore. Content is bundled with the functions — no AI involved. Idempotent: re-running bumps the version and refreshes all seeded surahs. Clients pick up new questions on next open.
Diagnoses the "Sender is not valid" (422) email-OTP failure. Lists the senders SendPulse considers valid and (optionally) fires a real test send so we can see the exact API response. Secrets stay server-side.
Who can sign into this admin panel. Stored centrally in Firestore —
changes apply within ~60 seconds across all functions, no
redeploy. admin@wasl.my is a built-in recovery
admin and is always allowed. One email per line.
Creates a Firestore profile for every Firebase Auth user that doesn't have one. Safe to run repeatedly — only touches users that are still missing a profile. Once backfilled, the user becomes editable in the panel (tier, refunds, delete, etc).
Lists every Firestore /users doc whose UID isn't in Firebase Auth's listUsers() result. READ-ONLY for now — the bulk delete was disabled after a case where real group members appeared here. Verify each row in Firebase Console before deciding anything. Use the per-user Delete on the user detail page if you genuinely want to remove a single one.
A summary email lands in ADMIN_EMAILS every Monday at 08:00 Asia/Singapore with week-over-week numbers (signups, tickets, SOS, AI queries, partner commission, banner status). Hit the button to send the current snapshot now — useful for previewing copy and double-checking the numbers without waiting for Monday.
One-time migration: writes the denormalised reactionCounts onto existing circle feed items from their reactions sub-collections, so counts are exact for posts made before the perf change. New reactions stay in sync automatically via a trigger. Safe to run more than once.
Create a promo code
Users redeem the code in Settings to unlock free Pro time. Use for marketing pushes, support recovery and ad-hoc gifts.
Existing codes
| Code | Grants | Uses | Expires | Status | Description |
|---|
Onboard a partner
Agencies, hotels and influencers who earn commission on the paid subscriptions of users they bring in. Each partner gets a permanent code users redeem in Settings to be attributed. Commission is one-time per user (20% by default of their first paid subscription).
Partners
| Partner | Code | Commission | Users brought | Paid | Earned | Status |
|---|
Onboard an agency
Hajj/Umrah agencies that sell Pilgrim Pass codes to pilgrims for cash. Each agency gets a pool of single-use codes they distribute offline. Pilgrim redeems in app → 30 days Wasl Pilgrim unlocked. Agency keeps a commission; Wasl invoices weekly for the rest.
Agencies
| Agency | Country | Pool | Active | Redeemed | Outstanding | Status |
|---|
—
Generate code batch
Single-use Pilgrim Pass codes tied to this agency. Codes go live immediately. Subject to pool cap.
Invoices
Pick a date range (default: last 7 days). Wasl bills the agency for the 80% owed on redeemed codes. Mark paid once their bank transfer / Stripe / cash settlement clears.
| Period | Redeemed | Total owed | Status | Generated |
|---|
Codes
| Code | Batch | Status | Expires | Created |
|---|
Recent redemptions
| When | Code | User | Wasl owed | Invoice |
|---|
Wasl Circles
| Circle | Kind | Members | Last activity | Created | Health |
|---|
—
Members
| Name | Role | Joined | Notifications |
|---|
Recent messages
| When | Author | Type | Preview |
|---|
Feature toggles
Kill-switches wired into the app for specific features. Pick a
state for each feature without releasing a new build. Mobile
clients pick the new state up on next launch (or sooner via
fetchAndActivate).
- Enabled — feature works normally.
- Disabled (show message) — feature is visible but greyed; tapping shows the shared "temporarily unavailable" snackbar (edit below).
- Hidden — feature does not render at all.
"Temporarily unavailable" message
Shown as a snackbar when a user taps a feature that's in the Disabled (show message) state. One shared message applies to every disabled feature. Keep it short (under 300 chars).
App update gate
Show users an update prompt. Soft = a dismissible nudge. Force = a full-screen block until they update. Both use a built-in message (English/Malay/Urdu). One tap — no build numbers needed. Only affects v121+ builds; cold-restart the app to see the change. Current state: checking…
Advanced — target specific builds & custom messages
Configuration parameters
Anything that isn't a feature on/off switch — API keys, model identifiers, threshold numbers, JSON blobs. Same Remote Config under the hood, different UX for the different shape of edit.
Configuration parameters
| Key | Type | Value | Description |
|---|
In-app banner
A ribbon at the top of every user's home screen. Use for incident comms ("we're aware of a maps slowdown"), seasonal announcements, or short heads-ups. Silent — no push notification.
Promo Cards
Full-card promotional units on the user's home screen — partner hotels, agencies, seasonal pushes, feature spotlights. Pick a theme, write the copy, schedule a window. Different from the ribbon banner (which is for outage / maintenance comms).
Users who used this code
| User | Via code | Joined | Subscribed | Last active |
|---|
Commission ledger
One-time commission per user, vested 30 days after first payment. Pending rows become payable after vesting; paid rows are settled.
| When | User | Product | Gross | % | Commission | State |
|---|
Codes for this partner
| Code | Used | Status | Description | Created |
|---|
Audit log
Recent admin write-actions across all targets. Newest first. Page size: 15.
| When | Admin | Action | Target | Details |
|---|