Firebase Setup & User Tracking
This guide explains how the app implements silent user tracking using Firebase Anonymous Authentication, Cloud Messaging (FCM), and location services.
Overview
The app automatically tracks users without any login or signup. When a user installs and opens the app:
- Anonymous Authentication - Assigns a permanent UID
- FCM Token - Enables push notifications
- Location Tracking - Gets user's current location
- Data Storage - Saves to Firebase Firestore
All of this happens silently in the background without user interaction.
Architecture
App Launch
↓
UserManager.initializeUser()
↓
Firebase Anonymous Auth → UID
↓
Firebase Messaging → FCM Token
↓
Save to Firestore (uid, fcmToken)
↓
Request Location Permissions
↓
Get Location → Update Firestore
Implementation Details
1. Firebase Dependencies
Added to app/build.gradle.kts:
// Firebase - Import the BoM
implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
// Firebase products
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-auth") // Anonymous auth
implementation("com.google.firebase:firebase-firestore") // User data storage
implementation("com.google.firebase:firebase-storage") // Photo storage
implementation("com.google.firebase:firebase-messaging") // Push notifications
// Google Play Services for Location
implementation("com.google.android.gms:play-services-location:21.3.0")
// Coil for image loading
implementation("io.coil-kt:coil-compose:2.5.0")
Why each dependency: - firebase-auth: Anonymous user authentication - firebase-firestore: Store user data (UID, FCM token, location) - firebase-storage: Future use for feast photos - firebase-messaging: Receive push notifications - play-services-location: Get user's GPS location - coil: Load images efficiently in Compose
2. Android Manifest Permissions
Added to AndroidManifest.xml:
<!-- Internet permission for Firebase -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Location permissions for tracking user location -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Notification permission (Android 13+) -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Why each permission: - INTERNET: Firebase requires network access - ACCESS_FINE_LOCATION: Get precise GPS coordinates - ACCESS_COARSE_LOCATION: Fallback for approximate location - POST_NOTIFICATIONS: Required for Android 13+ to show notifications
3. Firebase Cloud Messaging Service
Added BhandaraMessagingService.kt:
<!-- In AndroidManifest.xml -->
<service
android:name=".services.BhandaraMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Purpose: - Receives push notifications from Firebase - Displays notifications in system tray - Handles notification clicks to open the app
How it works: 1. Backend sends FCM notification 2. Firebase delivers to device 3. Service receives message 4. Creates and displays notification
Components
UserManager
Location: UserManager.kt
Responsible for: - Initializing anonymous users - Managing FCM tokens - Updating user locations - (Future) Syncing data to backend API
Key Methods:
- initializeUser(): Signs in anonymously and saves to Firestore
- updateUserLocation(): Gets GPS and updates Firestore
UserRepository
Location: UserRepository.kt
Handles Firebase operations:
- signInAnonymously(): Creates anonymous Firebase user
- getFcmToken(): Retrieves FCM device token
- saveUser(): Saves user data to Firestore
- updateUserLocation(): Updates location in Firestore
LocationHelper
Location: LocationHelper.kt
Manages location services:
- hasLocationPermissions(): Checks if permissions granted
- getCurrentLocation(): Gets precise GPS coordinates
- getLastKnownLocation(): Gets cached location (faster)
Data Models
User Model - User.kt:
data class User(
val uid: String = "",
val fcmToken: String = "",
val location: GeoPoint? = null,
val createdAt: Long = System.currentTimeMillis(),
val lastActive: Long = System.currentTimeMillis()
)
User Flow
First App Launch
- App Opens →
MainActivity.onCreate() - UserManager Initialized → Creates UserManager instance
-
initializeUser() Called:
-
Permissions Requested → Location and notifications
- Location Updated (if granted):
Subsequent App Launches
- App Opens
- Existing User Check → Firebase recognizes returning user
- Same UID Used → No new user created
- FCM Token Verified → Updated if changed
- Location Updated → Fresh GPS coordinates
Firebase Console Verification
Authentication
- Go to Firebase Console
- Select "bhandara" project
- Navigate to Authentication → Users
- See anonymous users with UID
Firestore Database
- In Firebase Console
- Navigate to Firestore Database
- Open users collection
- View documents with structure:
Cloud Messaging
- In Firebase Console
- Navigate to Cloud Messaging
- View registered FCM tokens
- Test notifications from console
Debugging
LogCat Tags
Monitor these tags in Android Studio Logcat:
UserManager: User initialization flowUserRepository: Firebase operationsLocationHelper: Location updatesBhandaraMessaging: Notification handling
Expected Log Sequence
UserManager: User signed in with UID: abc123def456
UserManager: FCM token obtained
UserRepository: User data saved successfully
UserManager: User saved to Firestore
LocationHelper: Location obtained: 18.5823749, 73.8844745
UserRepository: User location updated
UserManager: User location updated in Firestore
Common Issues
Location Not Updating
Problem: Location stays null in Firestore
Solutions: - Check permissions granted - Ensure emulator has location set (Extended Controls → Location) - Use device with GPS instead of emulator - Check Play Services installed on emulator
FCM Token Not Generated
Problem: fcmToken is empty
Solutions:
- Use emulator with Google Play (not just Google APIs)
- Check google-services.json is valid
- Verify internet connection
- Restart app
Anonymous User Not Created
Problem: UID is null
Solutions:
- Check Firebase Authentication is enabled
- Verify google-services.json configuration
- Enable Anonymous sign-in in Firebase Console
Security Considerations
Anonymous Auth Limitations
- Device-specific: UID tied to app installation
- Non-recoverable: Uninstall = new user
- No cross-device: Can't sync across devices
Privacy
- No personal information collected
- Only: UID, FCM token, location
- Users can't be identified
- Complies with anonymous usage
Data Retention
Consider implementing: - Remove users inactive for 90+ days - Clear location data older than 30 days - GDPR compliance for EU users
Next Steps
See Backend Integration for: - Syncing user data to PostgreSQL/PostGIS - Implementing backend API calls - Querying nearby users - Sending targeted notifications
Related Documentation
- Getting Started - Initial setup
- Architecture - Overall app structure
- Backend Integration - API implementation
- Development Guide - Best practices