agentsclimarketplace

Crashlytics setup

Skill almasumdev/awesome-mobile-observability-agent-skills/.github/skills/crash/crashlytics-setup

Agent skills for logging, metrics, tracing, crash reporting, and analytics in mobile apps.

Install
npx -y skills add almasumdev/awesome-mobile-observability-agent-skills --skill crashlytics-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Set up Firebase Crashlytics correctly across Android (Kotlin), iOS (Swift), Flutter, and React Native with custom keys, user ids, and release tagging. Use when adding or auditing Crashlytics integration.

SKILL.md

7.1 KB, as published. Nobody here has run it

Firebase Crashlytics Setup

Instructions

Follow these steps to wire Firebase Crashlytics into a mobile app so that every crash, non-fatal, and ANR is captured, symbolicated, and attributable to a release.

1. Prerequisites

  • A Firebase project with the app registered for every target platform (one app per bundle id / application id).
  • google-services.json (Android) and GoogleService-Info.plist (iOS) checked into the project or injected at build time per flavor.
  • Crashlytics enabled in the Firebase console for each app; ANR collection enabled under Android settings.
  • A release pipeline that can upload mapping files / dSYMs per build (see the symbolication skill).

2. Android (Kotlin) Integration

Add Gradle plugins in settings.gradle.kts or the root build.gradle.kts:

plugins {
    id("com.google.gms.google-services") version "4.4.2" apply false
    id("com.google.firebase.crashlytics") version "3.0.2" apply false
}

App module build.gradle.kts:

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.gms.google-services")
    id("com.google.firebase.crashlytics")
}

dependencies {
    implementation(platform("com.google.firebase:firebase-bom:33.5.1"))
    implementation("com.google.firebase:firebase-crashlytics-ktx")
    implementation("com.google.firebase:firebase-analytics-ktx") // required for user-level breadcrumbs
}

android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            configure<com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension> {
                mappingFileUploadEnabled = true
                nativeSymbolUploadEnabled = true
                unstrippedNativeLibsDir = file("build/intermediates/merged_native_libs/release/out/lib")
            }
        }
        getByName("debug") {
            configure<com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension> {
                mappingFileUploadEnabled = false
            }
        }
    }
}

Initialize in Application.onCreate:

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
        val crashlytics = FirebaseCrashlytics.getInstance()
        crashlytics.isCrashlyticsCollectionEnabled = BuildConfig.BUILD_TYPE == "release"
        crashlytics.setCustomKey("flavor", BuildConfig.FLAVOR)
        crashlytics.setCustomKey("build_number", BuildConfig.VERSION_CODE)
    }
}

3. iOS (Swift) Integration

Add the Firebase SPM package (https://github.com/firebase/firebase-ios-sdk) and include FirebaseCrashlytics and FirebaseAnalytics.

Add a Run Script build phase after [CP] Embed Pods Frameworks that runs:

"${PODS_ROOT}/FirebaseCrashlytics/run"

with input files $(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH) and $(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(EXECUTABLE_NAME).

Initialize in AppDelegate:

import FirebaseCore
import FirebaseCrashlytics

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        Crashlytics.crashlytics().setCustomValue(Bundle.main.infoDictionary?["CFBundleVersion"] ?? "?", forKey: "build_number")
        #if DEBUG
        Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)
        #endif
        return true
    }
}

4. Flutter Integration

# pubspec.yaml
dependencies:
  firebase_core: ^3.6.0
  firebase_crashlytics: ^4.1.3
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
  PlatformDispatcher.instance.onError = (error, stack) {
    FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
    return true;
  };

  await FirebaseCrashlytics.instance
      .setCrashlyticsCollectionEnabled(!kDebugMode);

  runApp(const MyApp());
}

Obfuscated release builds must pass --obfuscate --split-debug-info=build/symbols and you must upload the resulting symbols (see symbolication).

5. React Native Integration

yarn add @react-native-firebase/app @react-native-firebase/crashlytics
cd ios && pod install
import crashlytics from '@react-native-firebase/crashlytics';

export async function initCrashReporting(userIdHash: string, appVersion: string) {
  await crashlytics().setCrashlyticsCollectionEnabled(!__DEV__);
  await crashlytics().setUserId(userIdHash);
  await crashlytics().setAttributes({
    build_number: appVersion,
    js_engine: 'hermes',
  });
}

Configure firebase.json for automatic JS error capture:

{
  "react-native": {
    "crashlytics_javascript_exception_handler_chaining_enabled": true,
    "crashlytics_auto_collection_enabled": true
  }
}

6. Custom Keys and User Ids

  • User id: set a stable hashed user id (SHA-256(userId + app_salt)), never the raw id. Do not set emails or phone numbers.
  • Standard keys: release_channel, feature_flags_hash, last_screen, network_type, locale, experiment_bucket.
  • Breadcrumbs via logs: call log("navigated to /cart") at key state transitions; Crashlytics attaches the last 64 log lines to the crash.

7. Non-Fatals and ANRs

  • Capture caught exceptions that represent bugs with recordError / recordException so they surface alongside crashes.
  • Tag non-fatals with a severity custom key (low/med/high) so dashboards can filter.
  • ANRs are auto-captured on Android; you cannot opt specific traces out, but you can improve attribution by setting last_screen before any long-running operation.

8. Dashboards and Alerts

  • Pin the Crash-free users and Crash-free sessions panels for the last release.
  • Create Velocity alerts per app for new issues affecting more than 1% of sessions in the last hour.
  • Alert on ANR rate > 0.47% of daily users (Play Store bad-behavior threshold) with a burn-rate policy (see the alerting-sla skill).
  • Every alert must deep-link to the Crashlytics issue URL and include the affected release.

Checklist

  • Gradle plugin / SPM package / pub package added for the correct platform.
  • Collection disabled in debug, enabled in release.
  • Custom keys include release_channel, build_number, flavor.
  • User id is hashed, never raw.
  • Non-fatals use recordError/recordException with a severity key.
  • ANR collection is enabled (Android) and exercised in a staging build.
  • Mapping files / dSYMs upload in CI for every release build.
  • Velocity alert and crash-free SLO dashboards are pinned.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.