Skip to content

A modern, privacy-first Flutter app for logging rainfall. Track multiple gauges, visualize data with powerful charts, and keep your data secure on-device. Built with Riverpod, GoRouter, and Drift.

License

Notifications You must be signed in to change notification settings

astraen-dev/RainVu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

RainVu πŸ’§

RainVu is a modern Flutter app for farmers, gardeners, and weather enthusiasts to meticulously log rainfall from multiple custom gauges. It transforms raw data into actionable insights through powerful charts and historical analysis, all while keeping user data private and on-device.

✨ Key Features

  • πŸ“Š Data Logging & Management:

    • Quickly log rainfall entries with amount, date, and associated gauge.
    • Add, edit, and manage multiple custom rain gauges.
    • View all historical entries in a clean, organized list.
  • πŸ“ˆ Powerful Analytics & Insights:

    • Visualize data with charts for Month-to-Date (MTD) and Year-to-Date (YTD) totals.
    • Analyze monthly trends, seasonal patterns, and year-over-year comparisons.
    • Dive deep into daily breakdowns for any given month.
  • πŸ”„ Data Portability:

    • Export all your data to CSV or JSON formats for backup or external analysis.
    • Import data from a previously exported file to restore or merge records.
  • πŸ”’ Secure & Private:

    • All rainfall data is stored securely and locally on the user's device using a relational database.
    • No cloud account or internet connection is required for core functionality.

πŸ› οΈ Tech Stack & Architecture

This project is built with a modern, scalable Flutter stack emphasizing type-safety, code generation, and a feature-first architecture with distinct environments for development and production.

Core Technologies

  • Framework: Flutter & Dart
  • State Management: Riverpod with riverpod_generator for compile-safe providers.
  • Routing: GoRouter with go_router_builder for type-safe, declarative navigation.
  • Local Storage:
    • Drift (Moor): For reactive, persistent storage of relational data (gauges, entries).
    • shared_preferences: For simple key-value storage of user settings.
  • Telemetry:
    • Firebase Analytics: For anonymized usage metrics.
    • Firebase Crashlytics: For crash reporting.
  • Data Models: freezed for immutable data classes and unions.
  • UI & Visualization:
    • fl_chart for creating beautiful and interactive charts.
    • flutter_animate for declarative and easy-to-use animations.

Utility Packages

  • json_serializable: For robust JSON serialization/deserialization.
  • intl: For internationalization and date/number formatting.
  • file_picker & url_launcher: For file system and external link interactions.
  • build_runner: To run all code generation tasks.

Code Style & Linting

  • flutter_lints and riverpod_lint are used with a strict ruleset in analysis_options.yaml to maintain code quality and consistency.

Project Structure

The codebase follows a feature-first architecture and uses separate entry points for different build environments (flavors).

lib/
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ data/         # Shared data sources (Drift DB, SharedPreferences)
β”‚   β”œβ”€β”€ navigation/   # GoRouter configuration and routes
β”‚   β”œβ”€β”€ ui/           # App-wide UI (themes, navigation shell)
β”‚   └── utils/        # Shared utilities and extensions
β”‚
β”œβ”€β”€ features/
β”‚   β”œβ”€β”€ [feature_name]/
β”‚   β”‚   β”œβ”€β”€ application/  # Business logic & Riverpod providers
β”‚   β”‚   β”œβ”€β”€ data/         # Feature-specific repositories
β”‚   β”‚   β”œβ”€β”€ domain/       # Models and entities (often with Freezed)
β”‚   β”‚   └── presentation/ # UI (screens, widgets)
β”‚   └── ...
β”‚
β”œβ”€β”€ shared/
β”‚   β”œβ”€β”€ domain/       # Domain models shared across multiple features
β”‚   └── widgets/      # Reusable widgets (buttons, dialogs, etc.)
β”‚
β”œβ”€β”€ main_common.dart  # Shared app initialization logic
β”œβ”€β”€ main_dev.dart     # Entry point for the 'dev' flavor
└── main_prod.dart    # Entry point for the 'prod' flavor

πŸš€ Getting Started

Follow these instructions to set up the project for local development.

Prerequisites

  • Flutter SDK (version specified in pubspec.yaml)
  • An IDE like Android Studio or VS Code
  • An Android Emulator or physical device
  • An iOS Simulator or physical device (requires macOS with Xcode)
  • Firebase CLI installed and authenticated (firebase login).
  • Java Development Kit (JDK) to use keytool.

Setup

  1. Clone the repository:

    git clone https://github.com/astraen-dev/RainVu.git
    cd RainVu
  2. Install dependencies:

    flutter pub get
  3. Set up Firebase: This project uses Firebase for Analytics and Crashlytics, configured separately for dev and prod environments (flavors). To run the app, you must set up your own Firebase projects.

    • Create two Firebase projects in the Firebase Console: one for development (e.g., my-rainvu-dev) and one for production (e.g., my-rainvu-prod).
    • Enable Analytics and Crashlytics in both projects.
    • For each project, register an Android and an iOS app, making sure to use the correct package/bundle IDs:
      • Development: com.astraen.rainvu.dev (for both iOS and Android)
      • Production: com.astraen.rainvu (for both iOS and Android)
    • Run the flutterfire configure commands below, replacing the --project value with your own Firebase project IDs. This will generate the necessary firebase_options_*.dart files and native configuration files.

    Configure Development Firebase:

    flutterfire configure \
      --project=<YOUR_DEV_PROJECT_ID> \
      --out=lib/firebase_options_dev.dart \
      --ios-bundle-id=com.astraen.rainvu.dev \
      --android-package-name=com.astraen.rainvu.dev \
      --ios-out=ios/Runner/Firebase/dev/GoogleService-Info.plist \
      --android-out=android/app/src/dev/google-services.json

    Configure Production Firebase:

    flutterfire configure \
      --project=<YOUR_PROD_PROJECT_ID> \
      --out=lib/firebase_options_prod.dart \
      --ios-bundle-id=com.astraen.rainvu \
      --android-package-name=com.astraen.rainvu \
      --ios-out=ios/Runner/Firebase/prod/GoogleService-Info.plist \
      --android-out=android/app/src/prod/google-services.json
  4. Set up Android App Signing: To build a release version of the Android app, you need to configure an upload keystore.

    1. Generate an Upload Keystore: If you don't have one, create a keystore using the following keytool command. It will prompt you for passwords and other information. Remember the passwords you choose.

      keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
    2. Move the Keystore: Place the generated upload-keystore.jks file inside the android/ directory of the project.

    3. Configure Signing Properties: In the android/ directory, you will find a template file named key.properties.example.

      • Create a copy of this file and rename it to key.properties.
      • Open key.properties and fill in the passwords and alias you chose when generating the keystore.

      Note: The key.properties file is already listed in .gitignore and must never be committed to version control.

  5. Run code generation: This project heavily relies on code generation. Run build_runner to generate the necessary files:

    dart run build_runner build --delete-conflicting-outputs

πŸ’» Development Workflow

The app is configured with two environments, called "flavors": dev and prod. You must specify which flavor you want to run or build.

Running the App (Flavors)

Ensure an emulator/simulator is running or a device is connected.

  • To run the dev flavor: This version connects to your development Firebase project, has a .dev suffix in its application ID, and displays a "DEBUG" banner.

    flutter run --flavor dev -t lib/main_dev.dart
  • To run the prod flavor: This version connects to your production Firebase project and behaves as the release version would.

    flutter run --flavor prod -t lib/main_prod.dart

Building for Release

  • To build an Android App Bundle for production: After completing the app signing setup, run:
    flutter build appbundle --flavor prod -t lib/main_prod.dart
  • To build an iOS App for production:
    flutter build ipa --flavor prod -t lib/main_prod.dart

Code Generation

If you modify any file that uses code generation (e.g., Riverpod providers, Freezed models, Drift tables), you must re-run build_runner. For continuous development, use the watch command:

dart run build_runner watch --delete-conflicting-outputs

This will automatically regenerate files whenever you save a change.

Localization

The localization workflow involves several steps to keep the app_en.arb file clean and up-to-date.

  1. Remove unused keys (Optional):
    dart pub global run remove_unused_localizations_keys
  2. Sort keys and generate metadata (Optional):
    arb_utils generate-meta lib/l10n/app_en.arb
    arb_utils sort lib/l10n/app_en.arb
  3. Generate Dart localization files:
    flutter gen-l10n

Generating OSS Licenses

This project uses dart_pubspec_licenses to generate a list of open-source licenses for display within the app. After adding or updating packages, run the following command:

dart run dart_pubspec_licenses:generate

πŸ“„ License

This project is licensed under the MIT License. See the LICENSE file for details.

About

A modern, privacy-first Flutter app for logging rainfall. Track multiple gauges, visualize data with powerful charts, and keep your data secure on-device. Built with Riverpod, GoRouter, and Drift.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Languages