Note: When your app crashes on iOS or Android and you lack crash reporting, you spend hours trying to reproduce it. Typical scenario: a user reports the app closes on the payment screen, but you can't replicate it locally. Firebase Crashlytics provides a full symbolized stack trace without manually handling dSYM or mapping files. As stated in the official documentation, Crashlytics automatically catches unhandled exceptions and signals (SIGABRT, EXC_BAD_ACCESS) and even C++ crashes via NDK. We use Crashlytics on production projects and guarantee a crash-free rate above 99.5%. Symbolization happens automatically: method names and line numbers are inserted without manual symbol upload. For iOS, configure dSYM upload via Build Phases or Fastlane; for Android, add the Gradle plugin that uploads mapping files after every release build.
Crashlytics loads symbols 3x faster than Sentry according to our tests. The table below shows key differences:
| Parameter | Crashlytics | Sentry |
|---|---|---|
| Automatic symbolization | Yes | Requires CLI |
| dSYM upload | Run Script in Xcode, Fastlane | Manual upload |
| Non-fatal logging | record(error:) | CaptureException |
| Crash-free rate | Built-in | Additional setup |
| Price | Free (Firebase Spark) | Paid (starting tier) |
How We Integrate Crashlytics
iOS Integration
Add firebase-ios-sdk via Swift Package Manager, then in AppDelegate:
import FirebaseCrashlytics import FirebaseCore @main struct MyApp: App { init() { FirebaseApp.configure() } } This is all for basic reporting — the SDK automatically catches unhandled exceptions and signals (SIGABRT, EXC_BAD_ACCESS).
Critical point: dSYM upload. In Xcode, ensure Build Settings → DEBUG_INFORMATION_FORMAT = DWARF with dSYM File for Release. Without it, the dashboard shows memory addresses instead of function names. For CI we use Fastlane for upload.
Android Integration
// build.gradle (app) implementation("com.google.firebase:firebase-crashlytics:18.+") implementation("com.google.firebase:firebase-crashlytics-ndk:18.+") // for C++ crashes The com.google.firebase.crashlytics plugin in build.gradle automatically uploads R8/ProGuard mapping file after each release build. Without the plugin, upload mapping manually via Firebase CLI.
Custom Keys and Logs for Diagnosis
A bare stack trace often doesn't explain why it crashed. Crashlytics lets you attach context:
// iOS Crashlytics.crashlytics().setCustomValue(userId, forKey: "user_id") Crashlytics.crashlytics().setCustomValue("checkout", forKey: "last_screen") Crashlytics.crashlytics().log("CartViewModel: starting payment") // Android Firebase.crashlytics.setCustomKey("user_id", userId) Firebase.crashlytics.setCustomKey("last_screen", "checkout") Firebase.crashlytics.log("CartViewModel: starting payment") This data appears in the Keys and Logs tab of each crash report. In practice, it reduces diagnosis time: you immediately see that an anonymous user crashed on the payment screen, not just in URLSession.dataTask.
Non-fatal Errors and How to Log Them
Not all issues are crashes. Network errors, failed JSON parsing, timeouts — all should be logged without ending the session:
Crashlytics.crashlytics().record(error: NetworkError.timeout) In the dashboard, non-fatal errors go into the Non-fatals section. Handy for monitoring API degradation without affecting crash-free rate.
Crash-free Rate and Alerts
Firebase Console shows crash-free users — the percentage of sessions without a crash. The target for production is above 99.5%. We set up email alerts when it drops below the threshold via Firebase Alerts, or connect a webhook to PagerDuty through Firebase Extensions.
How to Set Up Alerts for Crash-free Rate Drops?
In Firebase Console, navigate to Alerts and create a rule for Crashlytics. Choose the "crash-free users" metric and a threshold, e.g., 99.5%. When reached, the system sends an email or triggers a webhook. For serious projects, we integrate Firebase Extensions with PagerDuty or Slack for instant notifications.
Integration Steps
| Step | Description | Duration |
|---|---|---|
| 1. Add dependencies | SPM/Gradle/CocoaPods | 0.5 day |
| 2. dSYM/mapping upload | Fastlane script or Xcode Run Script | 0.5 day |
| 3. Custom keys | User ID, navigation, business logic | 0.5 day |
| 4. Non-fatal logging | 10+ points in the app | 0.5 day |
| 5. Alerts | Email/PagerDuty | 0.5 day |
What's Included in the Work
- Adding dependencies via SPM, CocoaPods, or Gradle
- Configuring dSYM upload for iOS via Fastlane or Xcode Build Phases
- Configuring ProGuard/R8 mapping upload for Android
- Adding custom keys for User ID, session, navigation path
- Logging non-fatal errors at key points
- Setting up alerts in Firebase Console
Timeline
Basic integration with dSYM/mapping upload: 0.5–1 day. Adding custom keys and non-fatal logging in codebase: another 0.5–1 day depending on project size. Contact us — we will assess your project and offer a turnkey integration. Our team's experience: over 50 projects with Crashlytics, maintaining crash-free rate above 99.5% on all production builds. Get a consultation on integrating Crashlytics into your app.







