For the full story behind Test Nexus and how it works, read Why I Built Test Nexus.
Every developer knows the Crashlytics anxiety. You push a build to production, and then you wait. You refresh the Firebase console. You check your email for digest notifications. But in the world of mobile, minutes matter. If a fatal crash hits your top 10% of users, waiting for an hourly email summary is not an option.
In this deep dive, we cover Connected Apps — the system that turns passive Crashlytics monitoring into active, real-time push notifications on your phone.
The Problem with Dashboard Monitoring
Firebase Crashlytics is excellent at collecting crash data. But it’s a dashboard. Dashboards require you to be looking at them.
The standard monitoring workflow has three failure modes:
- Nobody’s watching. It’s 11 PM on a Friday. A crash is spiking. The dashboard faithfully records every occurrence. Nobody sees it until Monday morning’s standup.
- Email digests are too slow. Crashlytics sends daily or periodic summaries. By the time the email arrives, hundreds of users have already hit the crash.
- Alert fatigue. You set up Slack or email integrations. They fire for every non-fatal too. After a week, everyone ignores the channel.
Connected Apps solves all three by sending push notifications directly to your team’s phones — with configurable alert types so you only hear about what matters.
How It Works: The Architecture
Connected Apps uses a push-first architecture. Here’s the end-to-end flow:
- Your production app crashes. Crashlytics detects it — no code changes needed in your app.
- A Firebase Extension fires. You install our open-source Firebase Extension in your Firebase project. It listens for Crashlytics Eventarc triggers and sends an HTTP POST to the TestNexus backend.
- Secure token validation. The request includes a Bearer token (
tnx_prefix + 32 hex characters). The TestNexus Cloud Function hashes it with SHA-256 and looks up the matching connection. The plain token is never stored — only the hash. - FCM delivery. The function resolves all recipients for that connection and sends data-only FCM messages to each recipient’s registered devices.
- On-device notification. The TestNexus app receives the FCM payload, saves the crash data to a local encrypted database, and shows a push notification with the crash title, severity, and app name.
- Tap to inspect. Tapping the notification deep-links directly to the issue detail screen in Deep Inspector.
No crash data is stored on any server. The Cloud Function forwards metadata (issue title, subtitle, version) via FCM, and the app saves it locally in an AES-256 encrypted Room database. Your stack traces stay in your Firebase project.
Six Alert Types
Connected Apps doesn’t just detect crashes. When you create a connection, you choose which alert types to receive:
| Alert Type | What Triggers It | Severity |
|---|---|---|
| Fatal | Unhandled crash — app process dies | Critical |
| ANR | Application Not Responding (5+ second freeze) | High |
| Regression | A previously closed issue is happening again | High |
| Velocity | Crash rate is spiking rapidly | Critical |
| Non-fatal | Caught exception logged to Crashlytics | Medium |
| Digest | Daily stability summary from Crashlytics | Low |
Severity determines the notification behavior. Critical alerts trigger heads-up notifications with vibration. Low-priority digests appear silently.
Team Alerts: Up to 20 Recipients Per Connection
A connection isn’t just for you. When you generate a connection token, you add up to 20 recipient email addresses — each must be a TestNexus user.
Every recipient receives alerts independently via their own FCM tokens. If one person’s device is offline, everyone else still gets notified. The connection owner can add or remove recipients at any time from the Connection Detail screen, and all changes are recorded in an audit trail.
What this looks like in practice:
- Your Lead Dev and on-call engineer get Fatal and Velocity alerts
- Your QA lead monitors ANR and Regression alerts on a separate connection
- Your Product Manager gets a daily Digest summary on a third connection
Each connection has its own alert type configuration — create multiple connections to route different alert types to different groups.
Multi-App Monitoring
If you manage multiple apps in your Firebase project — or across multiple projects — each gets its own connection. The Connected Apps dashboard gives you a unified view:
- Status at a glance: Green dot = Active, Amber = Paused, Red = Revoked
- Alert count and last alert timestamp per connection
- Masked token display for identification without exposing secrets
Whether you’re monitoring staging, UAT, and production environments for one app, or a portfolio of 20 client apps, every connection is visible from one screen.
Alert Thresholds: Filtering the Noise
Not every crash deserves a push notification at 2 AM. Connected Apps lets you set thresholds per connection:
- Crash count threshold — only alert when the crash count exceeds N occurrences
- Crash percentage threshold — only alert when the affected user percentage exceeds N%
Alerts that don’t meet your thresholds are silently acknowledged (HTTP 200) but no notification is sent. This prevents notification fatigue during early development when non-fatal exceptions are expected.
Rate Limiting: Protection Against Crash Storms
When a critical bug hits production, Crashlytics can fire hundreds of alerts per minute. Connected Apps implements a 60-alert-per-minute sliding window per connection token. If the rate limit is exceeded, additional alerts receive a 429 response and are dropped until the window clears.
This protects your team from notification floods while ensuring the first 60 alerts per minute always get through.
Security Model
| Aspect | Implementation |
|---|---|
| Token format | tnx_ + 32 random hex characters (128 bits of entropy) |
| Storage | SHA-256 hash only in Firestore — plain token shown once at creation |
| Authentication | All app-facing functions require Firebase Auth + App Check |
| Webhook auth | Bearer token in HTTP header, validated via hash lookup |
| Data in transit | HTTPS only (Firebase-enforced) |
| Data at rest | No crash content in Firestore — only connection metadata |
| On-device storage | AES-256 encrypted Room database |
| FCM privacy | Each message includes recipientUid; wrong-user messages are silently dropped |
| Abuse prevention | Max 5 active connections per user, max 10 tokens per hour |
Setup in Under 5 Minutes
1. Generate a Connection Token
Open TestNexus → Connected Apps → tap + → enter an app name, add recipient emails, select alert types → tap Generate Token. Copy the token — it’s shown only once.
2. Install the Firebase Extension
Install the TestNexus Crashlytics Alerts Extension in your Firebase project. Configure:
- Webhook URL: the TestNexus Cloud Function endpoint
- Authorization:
Bearer tnx_<your-token> - Alert types: match your connection’s configuration
3. Start Receiving Alerts
The next time Crashlytics detects a matching event, you and your team get push notifications within seconds.
Managing Connections
Connection Lifecycle
Connections follow a simple state machine: Active → Revoked → Deleted.
- Active: Receiving alerts normally
- Revoked: Token is disabled, no new alerts accepted. Connection remains visible for reference.
- Deleted: Permanently removed along with rate limit data
Editing Recipients
From the Connection Detail screen, tap Edit Recipients to add or remove team members. The connection owner is always included and cannot be removed. Changes take effect immediately — the next alert routes to the updated list.
Batch Cleanup
Long-press any connection card to enter selection mode. Select multiple revoked connections and delete them in one action.
Connected Apps vs. Deep Inspector
These features complement each other:
| Aspect | Connected Apps | Deep Inspector |
|---|---|---|
| Data source | Firebase Crashlytics (production) | Device logcat (local) |
| Monitoring type | Remote — any platform | Local — apps on this device |
| Setup | Firebase Extension + token | One ADB permission grant |
| Alert content | Issue title, subtitle, version | Full stack trace + context logs + device state |
| Best for | Production monitoring | Development & QA debugging |
Use Connected Apps to know that a crash is happening in production. Use Deep Inspector to understand why it’s happening during development.
Get Started
- Download Test Nexus from Google Play
- Sign in with your Google account
- Open Connected Apps from the App Hub
- Create your first connection — name it, add your team, choose alert types
- Install the Firebase Extension in your project
- Paste your token in the extension configuration
Stop hunting for crashes. Let the crashes find you. Download Test Nexus →
What’s Next
- Post #04 — Deep Inspector: Automatic Crash Capture Without ADB — local crash capture for development
- Post #12 — Deep Inspector Beyond Crashes — ANR detection, health dashboard, and 7 issue types
- Post #10 — Building Your Complete Multi-Country Testing Workflow — all modules working together