Skip to content

Repository files navigation

Firebase Mobile Sensor Pusher & Cloud Visualizer 📱⚡

An Android application built in Kotlin that continuously reads real-time mobile hardware sensors (Accelerometer & Gyroscope), pushes timestamped data directly to Firebase Realtime Database, and visualizes historical cloud data using custom canvas charts.


📷 App UI Screenshot

Sensor Realtime DB Pusher UI


🔬 How It Works: End-to-End System Pipeline & Technology Mapping

This section details the step-by-step lifecycle of a sensor reading—from physical hardware motion to cloud persistence and real-time visualization—explaining exactly how each technology in the stack is utilized at each stage.

[ Hardware Sensors ]
        │
        ▼ (Android SensorManager API)
[ SensorReader Listener ]
        │
        ▼ (Volatile Vector3D Models)
[ Payload Builder ] ── (System.currentTimeMillis + Device ID)
        │
        ▼ (Kotlin Coroutines & OkHttp REST)
[ Firebase Realtime Database ] ── (Stored as JSON Node /sensor_readings)
        │
        ▼ (OkHttp GET Request & Gson Parser)
[ SimpleChartView Canvas ] ── (3-Axis X,Y,Z Line Charts)

Step 1: Hardware Sensor Acquisition (SensorReader.kt)

  • Technology Used: Android SensorManager Framework & SensorEventListener
  • Mechanism:
    1. SensorReader acquires instances of the default hardware accelerometer (Sensor.TYPE_ACCELEROMETER) and gyroscope (Sensor.TYPE_GYROSCOPE) via Context.getSystemService(Context.SENSOR_SERVICE).
    2. When listening starts (onResume), registerListener registers callbacks operating at SensorManager.SENSOR_DELAY_NORMAL.
    3. Whenever physical movement occurs, onSensorChanged(event: SensorEvent) triggers and extracts 3D axis floats (event.values[0], event.values[1], event.values[2]).
    4. Extracted values are immediately saved into thread-safe @Volatile Vector3D instance properties (latestAccel and latestGyro), ensuring lock-free, zero-latency access for background coroutines.

Step 2: Data Packaging & Coroutine Scheduling (MainActivity.kt)

  • Technology Used: Kotlin Coroutines (lifecycleScope), Gson
  • Mechanism:
    1. The user configures an upload interval $T$ (1 to 10 seconds) and presses Start Continuous Push.
    2. A background coroutine is launched on lifecycleScope.launch, running a periodic while (isActive) loop delayed by $T \times 1000\text{ ms}$.
    3. At every interval, a snapshot of the current sensor state is wrapped into a SensorDataPayload data class containing:
      • timestamp: Epoch milliseconds (System.currentTimeMillis())
      • deviceId: Unique device descriptor (Build.MANUFACTURER + "_" + Build.MODEL)
      • accelerometer: Vector3D(x, y, z)
      • gyroscope: Vector3D(x, y, z)
    4. Google Gson serializes this Kotlin data class into a clean JSON string payload.

Step 3: Cloud Transmission & Storage (FirebaseRealtimeDbUploader.kt)

  • Technology Used: OkHttp 4 HTTP Client, Firebase Realtime Database REST API
  • Mechanism:
    1. The app executes an asynchronous network call on Dispatchers.IO using OkHttp.
    2. A POST HTTP request containing the JSON payload is dispatched to https://micro-project-c8bad-default-rtdb.firebaseio.com/sensor_readings.json.
    3. If an optional authentication secret is provided, the query string ?auth=<token> is attached to satisfy Firebase Security Rules ("auth != null").
    4. Firebase assigns a unique push key (e.g., -O-a1b2c3d4e5f6) and persists the record under the /sensor_readings node.
    5. The HTTP response status (200 OK or 401 Unauthorized) is returned and appended to the live UI upload log view in MainActivity.

Step 4: Cloud Data Fetching (FirebaseRealtimeDbUploader.kt)

  • Technology Used: OkHttp 4, Gson TypeToken
  • Mechanism:
    1. In the Cloud Visualization tab (or when Auto Refresh is enabled), a GET request fetches the latest records from https://micro-project-c8bad-default-rtdb.firebaseio.com/sensor_readings.json.
    2. Firebase responds with a JSON map of push key objects.
    3. Gson deserializes the JSON response map into a Map<String, SensorDataPayload>.
    4. The payloads are sorted chronologically by timestamp and sliced to yield the most recent records for rendering.

Step 5: On-Screen Canvas Visualization (SimpleChartView.kt)

  • Technology Used: Custom Android View, Android Graphics Canvas & Paint APIs
  • Mechanism:
    1. The sorted list of sensor payloads is passed to SimpleChartView.setData(vectors).
    2. SimpleChartView extends android.view.View and overrides onDraw(canvas: Canvas).
    3. Canvas coordinates are calculated dynamically based on view dimensions (width, height).
    4. Zero-reference axes and grid lines are drawn using Paint.
    5. Sequential sensor values are mapped onto the Canvas space:
      • Red Line: $X$-axis values
      • Green Line: $Y$-axis values
      • Blue Line: $Z$-axis values
    6. canvas.drawLine() connects consecutive data points to render continuous 3-axis motion trajectory graphs for both Accelerometer and Gyroscope motion.

🛠️ Complete Technology Stack & Function Mapping

Technology Role in Stack Specific Function / Usage
Android Sensor Framework Hardware Integration Reads physical device TYPE_ACCELEROMETER & TYPE_GYROSCOPE values
Kotlin Coroutines Concurrency & Async Schedules non-blocking periodic streaming loops & network requests
Google Gson Data Serialization Converts Kotlin data classes (SensorDataPayload) to/from JSON strings
OkHttp 4 HTTP Networking Sends REST POST push calls and GET fetch requests to Firebase
Firebase Realtime DB Cloud Persistence Stores timestamped sensor records in JSON trees
Custom Canvas View Data Visualization Draws multi-axis line graphs ($X, Y, Z$) directly onto Android graphics canvas
Material Components UI Design Provides TabLayout, input controls, status labels, and activity structure

📊 Data Payload Schema

Data stored in Firebase Realtime Database under /sensor_readings:

{
  "-O6xY_abc123": {
    "timestamp": 1700000000000,
    "deviceId": "Google_Pixel_8",
    "accelerometer": {
      "x": -1.50,
      "y": 3.37,
      "z": 8.95
    },
    "gyroscope": {
      "x": -0.02,
      "y": -0.44,
      "z": 0.18
    }
  }
}

🔑 Firebase Setup & Troubleshooting HTTP 401

Endpoint URL: https://micro-project-c8bad-default-rtdb.firebaseio.com/

How to Fix HTTP 401 Unauthorized / Permission denied:

  1. Option A: Public Access (Recommended for testing) In Firebase Console -> Realtime Database -> Rules:
    {
      "rules": {
        ".read": true,
        ".write": true
      }
    }
  2. Option B: Authenticated Access If auth != null rules are enabled, copy your Database Secret from Firebase Console -> Project Settings -> Service Accounts -> Database Secrets, and enter it into the Auth Secret field in the app UI.

⚙️ Building & Running the Project

# Clone the repository
git clone <repo-url>
cd <repo-folder>

# Run unit tests
./gradlew test

# Build debug APK
./gradlew assembleDebug

The pre-compiled executable APK is available at apk/app-debug.apk.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages