Implement your own in-house Crashlytics for Android

Why For years, Crashlytics by Fabric was the gold standard for mobile crash reporting. It was fast, reliable, deeply integrated with Android tooling, and free. Teams adopted it without hesitation, and it became load-bearing infrastructure for mobile development at companies of every size. Then Google acquired Fabric. The migration from Fabric Crashlytics to Firebase Crashlytics was manageable for many teams, but it immediately raised a set of questions we could not get clear answers to. Firebase tools, as a rule, depend on Google Play Services — a hard requirement that excludes Huawei devices running HMS (Huawei Mobile Services) and the Chinese Android ecosystem more broadly, where GMS is not available. China represented a significant portion of our user base, and the prospect of running two parallel crash reporting systems — one for GMS markets, one for HMS — was operationally unappealing. ...

April 23, 2020 · 8 min · Anatolii Afanasev

Filter out classes from JaCoCo report using annotaitons

Story Engineering culture at scale is difficult to build and even harder to maintain. In our company, we made a deliberate decision to enforce code coverage as a merge requirement — a hard gate on the CI pipeline that prevented branches from being merged unless they met a minimum threshold. We chose 80%: every new or modified class had to be covered by unit tests to at least that level. ...

April 10, 2020 · 7 min · Anatolii Afanasev

Exclude properties from toString() of Kotlin data class (Sekret appx.)

This post describes how to remove class properties from the toString() method manually if you prefer not to use the Sekret compiler plugin. Kotlin’s data class toString is generated automatically to include every property defined in the primary constructor. This is convenient for debugging but problematic when some of those properties contain sensitive data — passwords, tokens, PII — that must not appear in logs, crash reports, or analytics pipelines. There is no built-in Kotlin mechanism to exclude a specific field from the generated toString while keeping it in equals, hashCode, and copy. The language does not (yet) offer an annotation equivalent to @Transient for serialization. The approaches below represent the practical trade-offs available in pure Kotlin, each with distinct implications for class semantics, mutability, and maintainability. ...

August 13, 2019 · 6 min · Anatolii Afanasev

Sekret — risk-free toString() of Kotlin data class?

Problem One of Kotlin’s most appreciated features is the data class. With a single keyword, the compiler automatically generates equals, hashCode, copy, componentN, and toString — eliminating an entire category of boilerplate that Java developers had to write and maintain by hand. For domain objects, value types, and state containers, data classes are the obvious choice. The toString function, in particular, is invaluable for debugging. When you log a data class instance, you get a complete, readable snapshot of its state: every field name and value, formatted cleanly. This is exactly what you want during development. ...

August 13, 2019 · 6 min · Anatolii Afanasev

KSON — auto-generate GSON adapters for Kotlin data classes

Kotlin data classes are an ideal fit for API response models. They are concise, immutable by default, and come with auto-generated equals, hashCode, copy, and toString — everything you need from a value object representing a network payload. Pairing them with GSON is natural and widely practiced across the Android ecosystem. However, there is a subtle but serious trap hiding in that combination — one that silently violates Kotlin’s type safety guarantees and can cause crashes that are difficult to reproduce and frustrating to diagnose. ...

August 12, 2019 · 5 min · Anatolii Afanasev