Skip to content

Firebase Crashlytics — Complete Guide

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about Firebase Crashlytics. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Crashlytics doesn't report crashes from your release build, or you can't find the root cause because logs and breadcrumbs are missing from crash reports.

Wrong Approach ❌

// No user ID — can't identify which users are affected
FirebaseCrashlytics.getInstance().recordException(Exception("Something went wrong"))

// Logging without context
FirebaseCrashlytics.getInstance().log("Button clicked") // Too vague

Output: Crashes recorded but hard to diagnose. No user context.

Right Approach ✅

class App : Application() {
    override fun onCreate() {
        super.onCreate()

        // Initialize Crashlytics (automatic with Firebase plugin)
        FirebaseCrashlytics.getInstance().apply {
            // Set user identifier for tracking
            setUserId(userId)

            // Set custom keys for crash context
            setCustomKey("app_version", BuildConfig.VERSION_NAME)
            setCustomKey("build_type", if (BuildConfig.DEBUG) "debug" else "release")
            setCustomKey("api_level", Build.VERSION.SDK_INT)
            setCustomKey("experiment_group", "control")

            // Add breadcrumbs for navigation path
            log("App launched")
        }
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Log breadcrumbs
        FirebaseCrashlytics.getInstance().log("MainActivity.onCreate")

        // Record non-fatal exceptions
        try {
            riskyOperation()
        } catch (e: Exception) {
            FirebaseCrashlytics.getInstance().recordException(e)
        }
    }

    private fun riskyOperation() {
        // ...
    }

    // Force a crash for testing
    fun testCrash() {
        FirebaseCrashlytics.getInstance().apply {
            log("Testing crash")
            setCustomKey("test_timestamp", System.currentTimeMillis())
        }
        throw RuntimeException("Test crash — verify in Firebase console")
    }
}

// In ViewModel
class MyViewModel @Inject constructor(
    private val crashlytics: FirebaseCrashlytics
) : ViewModel() {
    fun performAction() {
        crashlytics.log("User performed action X")
        crashlytics.setCustomKey("current_screen", "home")
        // ... do work
    }
}

Output: Crashes reported with full context and breadcrumb trail.

Prevention

  • Set setUserId() to identify affected users.
  • Add breadcrumbs with log() for the user's navigation path.
  • Record non-fatal exceptions with recordException().
  • Test Crashlytics with crash() in debug builds.
  • Enable debug mode: adb shell setprop debug.<a href="/apis/firebase/">Firebase</a>.Crashlytics.app .your.package.name.

Common Mistakes with Firebase Crashlytics

  1. Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
  2. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  3. Misunderstanding that String is [Char] with poor performance for large text operations

These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why are my crashes not appearing in the dashboard?

Check: (1) Crashlytics is enabled in the build, (2) you're running a release build without a debugger attached, (3) FirebaseCrashlytics.getInstance().sendUnsentReports() is called if needed.

### What is the difference between log and recordException?

log() adds a breadcrumb to the next crash report. recordException() sends a non-fatal error report immediately. Use both — log() for breadcrumbs, recordException() for caught exceptions.

### Can I filter crashes by user or custom key?

Yes. In the Firebase Console, you can filter crash reports by User ID, custom keys, or any breadcrumb text. This helps narrow down device-specific issues.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro