Skip to content

feat(android): implement T3 Connect end to end#3926

Open
shivamhwp wants to merge 7 commits into
pingdotgg:mainfrom
shivamhwp:feat/android-t3-connect-end-to-end
Open

feat(android): implement T3 Connect end to end#3926
shivamhwp wants to merge 7 commits into
pingdotgg:mainfrom
shivamhwp:feat/android-t3-connect-end-to-end

Conversation

@shivamhwp

@shivamhwp shivamhwp commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements T3 Connect end to end for Android using the existing Expo Push Service. No direct Firebase integration or new push provider is introduced.

Root cause

Android preview builds could authenticate, but first-run mobile identity creation could fail before environment bootstrap. The mobile registration and agent-awareness delivery paths were also iOS-only, so Android could not register an Expo push token or receive T3 Connect status and actionable updates.

What changed

  • Generate and persist a stable cryptographically random mobile device ID, while allowing environment connection to proceed if identity loading fails.
  • Register Android devices and Expo push tokens with the relay, including permission, channel, foreground refresh, and token-rotation handling.
  • Extend relay contracts, persistence, and migration data for Android device metadata and Expo push tokens.
  • Deliver quiet replaceable agent-status notifications and separate high-priority approval/input/completion/failure alerts through Expo.
  • Reconcile Expo tickets and receipts, record provider outcomes, and invalidate rejected device tokens.
  • Preserve the existing APNs and iOS Live Activity paths while sharing notification preference logic.
  • Add Android settings state, notification tap deep links, web device labels, and focused coverage.

Validation

  • vp check (0 errors; 9 pre-existing React warnings)
  • vp run typecheck
  • vp run lint:mobile (native source scan passed; optional local SwiftLint/ktlint/detekt tools were unavailable)
  • Focused relay, mobile, client-runtime, and web tests: 20 files / 171 tests passed
  • Android preview debug APK assembled successfully as com.t3tools.t3code.preview
  • Direct Fable 5 implementation review: no blocking or high-confidence correctness, security, migration, or iOS-regression bugs; ready for user testing

Testing note

End-to-end push testing requires a preview/dev-client build produced with the existing Expo/EAS Android push credentials and a relay deployment containing this migration and worker code. The repository does not add or configure Firebase.


Note

High Risk
Touches relay push delivery, DB migration with a unique expo_push_token index, and device registration transactions; mis-deployed migration or missing EAS credentials can break preview builds or silently disable Android push until a new native build.

Overview
End-to-end Android T3 Connect now registers devices with Expo push tokens, embeds Firebase via google-services.json, and delivers agent status and alerts through the relay’s Expo Push Service path while iOS APNs / Live Activities stay unchanged.

On mobile, Android joins agent-awareness registration: expo-notifications plugin and notification channels, permission flow, expoPushToken in relay payloads, FCM rotation handling, settings copy for Android, and more resilient device ID creation and connection when identity load fails.

On relay, a migration adds expo_push_token, android_api_level, and delivery-provider fields; device registration is transactional with Expo token claim/invalidate rules; ExpoPushClient / ExpoPushDeliveries send quiet status vs high-priority alerts (shared transition logic with APNs); receipts reconcile and bad tokens are cleared.

CI/docs require T3CODE_ANDROID_GOOGLE_SERVICES_FILE for EAS preview fingerprinting; credentials are gitignored.

Reviewed by Cursor Bugbot for commit cf7ea38. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Implement Android push notifications end-to-end via Expo push delivery

  • Adds Android device registration to the mobile app, fetching an Expo push token and sending platform: 'android', androidApiLevel, and expoPushToken to the relay; iOS registration behavior is unchanged.
  • Introduces ExpoPushClient and ExpoPushDeliveries relay services that send Expo push messages for Android targets and periodically reconcile Expo receipts via a new cron step in the relay worker.
  • Extends the relay DB schema (via migration) to store expo_push_token, android_api_level, and provider metadata columns (delivery_provider, provider_status, provider_id) on delivery attempts and mobile devices.
  • Adds configureAgentAwarenessNotificationChannels to create two Android notification channels (t3-connect-activity and t3-connect-alerts) and gates these on Android at runtime; notification permission and settings UI now supports Android.
  • Extracts shared transition logic (newlyAttentionRows, freshNewlyTerminalRows, shouldUpdateLiveActivity) into agentActivityTransitions.ts and agentAwarenessPreferences.ts, consumed by both APNs and Expo delivery paths.
  • Adds resolveAndroidGoogleServicesFile build-time validation for google-services.json and fails the EAS preview CI job early if the file is missing.
  • Risk: the new unique index on expo_push_token will reject duplicate tokens at the DB level; ios_major_version is now nullable, requiring any code that assumed it was non-null to handle null.

Macroscope summarized cf7ea38.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 118cbb58-df87-48ba-81af-03ac7228246a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Jul 13, 2026
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XS 0-9 changed lines (additions + deletions). labels Jul 13, 2026
Comment thread apps/mobile/src/features/agent-awareness/remoteRegistration.ts Outdated
@shivamhwp shivamhwp added the 🚀 Mobile Continuous Deployment Trigger Expo preview build label Jul 13, 2026
shivamhwp and others added 2 commits July 14, 2026 11:40
…ew env

Android push (T3 Connect) requires FCM: without google-services.json in the
APK, expo-notifications cannot mint an Expo push token and device
registration silently degrades. Wire android.googleServicesFile from the
T3CODE_ANDROID_GOOGLE_SERVICES_FILE EAS file variable (sensitive visibility
so preview CI can pull it for the native fingerprint), validate the file
registers the variant's Android package, and fail Android EAS preview
builds fast when the variable is missing so a broken-notifications APK can
never build again. Delivery stays app -> Expo push token -> relay -> Expo
Push Service -> FCM; no firebase SDK is added.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
preferences.test.ts and linkEnvironment.test.ts import modules that
transitively reach expo-crypto, whose expo-modules-core import reads the
React Native __DEV__ global that does not exist under the node test
runner. Mock the native modules like the sibling suites already do.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@shivamhwp shivamhwp marked this pull request as ready for review July 14, 2026 06:21
@macroscopeapp

macroscopeapp Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a complete new feature (Android push notifications) with database schema migrations, new Expo push delivery infrastructure, contract changes, and cross-cutting modifications. New features with schema impact and significant runtime behavior warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Comment thread infra/relay/src/agentActivity/ExpoPushDeliveries.ts Outdated
Comment thread infra/relay/src/agentActivity/Devices.ts Outdated
Comment thread infra/relay/src/agentActivity/ExpoPushDeliveries.ts Outdated
Comment thread apps/web/src/components/clerk/MobileClientsUserProfilePage.logic.ts Outdated
- Android alerts now mirror the iOS transition rules: they ring only when a
  thread newly enters an attention phase or freshly finishes relative to the
  per-device last-delivered aggregate, so republishes, reconnect replays, and
  stale completions stay silent. The shared transition logic moves to
  agentActivityTransitions.ts and ApnsDeliveries delegates to it.
- An alert-eligible publish also repaints the quiet status notification when
  live updates are enabled, so the shade never shows stale running content
  beside a completion alert. Expo deliveries persist the delivered aggregate
  via LiveActivities.markDelivery (and advance it silently on drift when the
  status channel is off) so transitions have a baseline.
- Android device registrations are authoritative for expoPushToken: a
  re-registration without a token (permission revoked) clears the stored one
  instead of coalescing it back.
- Android FCM token rotations carry a monotonic marker so they are never
  coalesced into an in-flight registration that already read the
  pre-rotation token.
- The mobile clients profile page treats an omitted androidApiLevel like
  null instead of rendering 'Android API undefined'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread infra/relay/src/agentActivity/Devices.ts Outdated
Comment thread infra/relay/src/agentActivity/ExpoPushDeliveries.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f2a839b. Configure here.

Comment thread infra/relay/src/agentActivity/ExpoPushDeliveries.ts
shivamhwp and others added 2 commits July 14, 2026 14:34
Advancing the transition baseline on any accepted delivery meant a
successful quiet status could consume an attention/terminal transition
whose high-priority alert failed, and the missed ring would never retry.
The baseline now only advances when the alert (if one was due) was
accepted, so the next publish recomputes and retries the transition.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The claims null the unique push-token columns on whichever rows own them
before the upsert re-inserts them on the registering device. Running them
as separate statements meant a failed upsert stranded the token — cleared
from its old row, owned by none — silently disabling push delivery until
the next successful registration. The claims and upsert now commit
atomically so a failure rolls the claims back.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚀 Mobile Continuous Deployment Trigger Expo preview build size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant