Firebase: Setup & Analytics

Every feature TrailLog has built so far runs entirely on the device — trails are saved to Room, files sit in local storage, and there's no server anywhere. That's fine for a single-user hiking journal, but the moment TrailLog wants to do anything involving an account, syncing across devices, or notifying a user of something that happened remotely, it needs a backend. Firebase is Google's suite of ready-made backend services — you don't run your own server, you just add a library and call an API. This lesson wires TrailLog up to a real Firebase project and adds the first (and simplest) product: Analytics. The three lessons after this one build on the exact same project for Authentication, Firestore, and Cloud Messaging.

Creating a Firebase Project and Connecting TrailLog

Everything starts in the Firebase Console (console.firebase.google.com), which is a web dashboard, not code. The steps are the same for any Android app:

StepWhat you do
1Click Add project, give it a name (e.g. "TrailLog"), and finish the short creation wizard.
2Inside the project, click the Android icon to register a new Android app.
3Enter TrailLog's application ID exactly as it appears in the app-level build.gradle.kts (e.g. com.codingwithsonu.traillog) — this is how Firebase matches incoming data to the right app.
4Download the generated google-services.json configuration file.
5Place that file in the app module's root directory — the same folder as the app-level build.gradle.kts.

google-services.json: What It Is and Why It's Sensitive

google-services.json is a small JSON file the Gradle plugin reads at build time. It contains project identifiers Firebase needs to route TrailLog's requests to the correct project — things like the Firebase project ID, the app's package name, and API keys scoped to that project. These values aren't secret in the sense of a password (they're baked into every compiled APK anyone installs, so they're technically recoverable), but if TrailLog's source repository is public, it's still good practice to keep this file out of public version control: it makes the project identifiers easy to find and reduces the chance of someone else's app accidentally being configured against your Firebase project, or your Firebase quota being probed by people who never even installed the app.

Note: A private repository shared only with your own team is a different situation — plenty of real projects commit google-services.json there. The concern is specifically about making it visible on a public repository.

Adding the Google Services Gradle Plugin

The Gradle plugin is what actually reads google-services.json during the build and generates the resources Firebase's libraries expect. It's declared in two places — once at the project level to make the plugin available, and once at the app level to apply it to TrailLog's module:

Project-level build.gradle.kts

plugins {
    id("com.android.application") version "8.4.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.23" apply false
    id("com.google.gms.google-services") version "4.4.1" apply false
}

App-level build.gradle.kts

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.gms.google-services") // applies the plugin that reads google-services.json
}

dependencies {
    // the Firebase BoM — see the next section
    implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
    implementation("com.google.firebase:firebase-analytics")
}

After adding this, syncing the project runs the plugin, which validates that google-services.json is present and matches the app's application ID — if the two don't match, the build fails immediately with a clear error rather than silently misbehaving at runtime.

The Firebase BoM: Keeping Every Library Version in Sync

Notice the app-level dependencies above never specify a version for firebase-analytics itself. That's because of the line just above it — implementation(platform("com.google.firebase:firebase-bom:33.1.0")). The Firebase Bill of Materials (BoM) is a single dependency that pins compatible versions for every Firebase library at once. As TrailLog adds Auth, Firestore, and Messaging in the next three lessons, each one is added without its own version number, and the BoM guarantees they're all versions Google has actually tested together — bumping one number, the BoM version, upgrades every Firebase library consistently instead of hunting down version mismatches one at a time.

Firebase Analytics: Automatic and Custom Events

Firebase Analytics is the first product to add because it needs almost no code — once the dependency above is in place, it automatically starts logging useful events on its own: screen_view whenever the user navigates to a new screen, app_open when TrailLog launches, and several others, all without a single line of extra code. Where Analytics becomes genuinely useful for understanding TrailLog's users is custom events — recording things that only make sense in TrailLog's own domain, like how often someone actually logs a trail.

Logging a custom event when a trail is saved

class TrailRepository(
    private val trailDao: TrailDao,
    private val analytics: FirebaseAnalytics
) {
    suspend fun saveTrail(trail: Trail) {
        trailDao.insert(trail)

        val params = Bundle().apply {
            putString("trail_name", trail.name)
            putDouble("distance_km", trail.distanceKm)
        }
        // A custom event — shows up in Firebase Analytics alongside the automatic ones
        analytics.logEvent("trail_logged", params)
    }
}

FirebaseAnalytics.getInstance(context) (or Firebase.analytics using the Kotlin extensions) gives you the singleton instance to call logEvent on. Event names and parameter keys are just strings, so it's worth being consistent — trail_logged with a distance_km parameter here lets you later build a report answering something like "what's the average distance of a logged trail," directly from the Firebase Console, with no backend code of your own.

Verifying Events with DebugView

Regular Analytics reports in the Firebase Console can take hours to populate — not useful while you're actively testing a new event. DebugView is a separate view built for development: once a device or emulator is put into debug mode for Analytics, every event it logs appears in the console within seconds, letting you confirm trail_logged fires with the parameters you expect the moment you save a trail, instead of waiting to find out the next day.

Note: These are correct, working Firebase/Gradle configurations, but this website's own project doesn't run a live Android Studio build or a real Firebase project, so nothing here actually connects or logs events on the page itself.

What's Coming: The Firebase Products This Track Covers

Analytics is the easiest Firebase product to add, but the project you just created is shared by every Firebase feature TrailLog uses from here on:

ProductWhat it's for in TrailLog
AuthenticationSign-up, login, and password reset, without TrailLog hosting its own account system — covered next.
Cloud FirestoreA cloud-hosted, real-time database so a user's trails sync across their devices, on top of Room's local storage.
Cloud Messaging (FCM)Push notifications — e.g. telling a user their hiking buddy just logged a new trail.
Up next: Firebase Auth adds real user accounts to TrailLog — sign-up, login, and sign-out — using the exact project you just connected.