{"id":47928951,"url":"https://github.com/davideagostini/dunio","last_synced_at":"2026-04-08T19:00:28.064Z","repository":{"id":348472178,"uuid":"1188733788","full_name":"davideagostini/dunio","owner":"davideagostini","description":"Mobile-first Android app for shared household finance tracking with Firebase and Jetpack Compose.","archived":false,"fork":false,"pushed_at":"2026-04-03T11:41:54.000Z","size":18343,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-04T07:19:06.542Z","etag":null,"topics":["android","firebase","firestore","hilt","household-finance","jetpack-compose","kotlin","material3","mobile-app","personal-finance"],"latest_commit_sha":null,"homepage":"https://dunio.app","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davideagostini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"davideagostini","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"davideagostini","thanks_dev":null,"custom":null}},"created_at":"2026-03-22T14:09:20.000Z","updated_at":"2026-04-03T11:41:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/davideagostini/dunio","commit_stats":null,"previous_names":["davideagostini/summ","davideagostini/dunio"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/davideagostini/dunio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideagostini%2Fdunio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideagostini%2Fdunio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideagostini%2Fdunio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideagostini%2Fdunio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davideagostini","download_url":"https://codeload.github.com/davideagostini/dunio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davideagostini%2Fdunio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31569400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","firebase","firestore","hilt","household-finance","jetpack-compose","kotlin","material3","mobile-app","personal-finance"],"created_at":"2026-04-04T07:09:23.501Z","updated_at":"2026-04-08T19:00:28.051Z","avatar_url":"https://github.com/davideagostini.png","language":"Kotlin","funding_links":["https://github.com/sponsors/davideagostini","https://buymeacoffee.com/davideagostini"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"site/assets/cover.png?v=20260402-1\" alt=\"Track net worth in one place\"\u003e\n\u003c/div\u003e\n\n\u003cdiv id=\"user-content-toc\"\u003e\n  \u003cul style=\"list-style: none;\"\u003e\n    \u003csummary\u003e\n      \u003cimg src=\"app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp\" alt=\"Dunio Logo\" width=\"120\" align=\"left\" hspace=\"20\"\u003e\u003ch1\u003eDunio\u003c/h1\u003e\n      \u003cp\u003e\n      \u003ca href=\"https://github.com/davideagostini/dunio/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/davideagostini/dunio?logo=github\u0026labelColor=1a1a1a\"\u003e\u003c/a\u003e\n      \u003ca href=\"https://opensource.org/license/mit\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-Mit%202.0-blue.svg\" alt=\"License\"\u003e\u003c/a\u003e\n      \u003ca href=\"https://kotlinlang.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/Kotlin-2.3.0%2B-blue\" alt=\"Kotlin\"\u003e\u003c/a\u003e\n    \u003c/summary\u003e\n  \u003c/ul\u003e\n\u003c/div\u003e\n\nDunio is a mobile-first Android app for shared household finance tracking.\n\nIt is designed for small shared workspaces such as couples or families who want a simple way to track:\n\n- net worth\n- assets and liabilities\n- income and expenses\n- recurring transactions\n- monthly household progress\n\nThe app is intentionally not an accounting suite. The focus is fast daily use, clear numbers, and a simple shared-household model backed by Firebase.\n\n## Screenshots\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cimg src=\"site/assets/screenshots/1.png\" alt=\"Track net worth in one place\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/2.png\" alt=\"Track every transaction\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/3.png\" alt=\"Manage assets and liabilities\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/4.png\" alt=\"Made for shared finances\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/5.png\" alt=\"Add transactions faster\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/6.png\" alt=\"Widgets for quick access\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/7.png\" alt=\"Faster than opening the app\" width=\"25%\"\u003e\u003cimg src=\"site/assets/screenshots/8.png\" alt=\"Built for day and night\" width=\"25%\"\u003e\n\u003c/p\u003e\n\n## What this repository contains\n\n- Android app source code\n- Gradle project files\n- GitHub CI workflow\n- contribution and release documentation\n\n## Core product model\n\nAll financial data belongs to a `household`.\n\nSupported roles:\n\n- `owner`\n- `member`\n\nBoth users share the same data inside a household:\n\n- dashboard\n- assets\n- transactions\n- categories\n- recurring transactions\n- month close state\n\nEach household uses one shared currency configured from Settings. The app does not support per-asset currencies or mixed-currency totals.\n\n## Current feature set\n\n### Authentication and household\n\n- Google sign-in with Firebase Authentication\n- persistent session restore\n- create household\n- join household with invite + household ID\n- owner/member household model\n- household onboarding keeps the user behind a loading state until session access is fully resolved\n\n### Dashboard\n\n- net worth\n- total assets\n- total liabilities\n- monthly cash flow\n- savings rate\n- financial runway\n- 3 / 6 / 12 month net worth chart\n- month selector\n- full-screen get-started flow for households missing entries or assets\n\nThe dashboard now renders a lightweight skeleton state while its monthly summaries load, so the screen structure appears immediately instead of blocking behind a generic full-screen spinner.\n\n### Entries\n\n- monthly transaction list\n- Firestore reads scoped to the selected month instead of the full household history\n- grouped by day\n- search\n- entries / reports toggle in the toolbar\n- `All / Expenses / Income` filter\n- unusual spending insights\n- category spending report with a horizontal bar chart plus totals, averages, percentages, and transaction counts\n- entry edit and delete flow\n- quick-entry flow\n\nThe entries screen now keeps the list and category reports month-scoped, while unusual-spending insights read only a small rolling window around the selected month instead of the full transaction archive.\nIt also renders a local shimmer skeleton during cold loads, so tab switches feel immediate even on slower devices.\n\n### Assets\n\n- monthly asset snapshots\n- Firestore reads scoped to the selected month plus the previous month instead of the full asset history\n- assets and liabilities in one feature\n- search\n- edit and delete flow\n- copy previous month snapshot\n- monthly net worth summary\n- household currency applied automatically to new asset snapshots\n\nThe assets screen now reads only the selected month and previous month snapshots so list rendering, month-over-month change, and `Copy previous month` stay responsive without downloading the full asset archive.\nLike Entries, it now uses a local shimmer skeleton during cold loads instead of blocking the whole app shell.\n\n### Settings\n\n- household currency\n- app language selection\n- app theme selection\n- household data export to CSV or JSON\n- category management\n- recurring transactions\n- month close\n- household members\n- invite management\n- household details\n\nThe household currency is changed from a dedicated searchable settings screen, and the selected currency is surfaced at the top of the list.\n\nThe app also includes a dedicated language selection screen in Settings. It uses the same list style as the currency screen, keeps a stable alphabetical order, and highlights the currently selected language.\n\nThe app theme is also changed from a dedicated Settings screen using the same list treatment as language selection. Users can choose `Light`, `Dark`, or `System`, and the selected theme is persisted across launches.\n\nThe app also includes a dedicated export screen in Settings. It can export the current household as a full JSON backup, plus entries and assets as CSV files through the Android system document picker.\n\nRecurring transactions can also be auto-applied on app startup. Once per day, after the session is ready, the app checks whether the current household has due recurring items for the current month and materializes them into the entries list without requiring a manual `Apply due` tap.\n\nThe month-close screen now reads only the selected month's entries and asset snapshots instead of loading the full transaction and asset history.\n\nBottom navigation now restores state across the primary tabs (`Dashboard`, `Entries`, `Assets`, `Settings`) so rapid tab switching reuses warm screens more reliably.\n\nCurrent app-language support includes:\n\n- English\n- Italian\n- French\n- German\n- Dutch\n- Spanish\n- Portuguese (Brazil)\n- Russian\n- Arabic\n- Chinese (Simplified)\n- Japanese\n\n### Quick access\n\n- Quick Settings tile\n- home-screen quick-entry widget\n- home-screen spending summary widget\n\n## Tech stack\n\n- Kotlin\n- Jetpack Compose\n- Material 3\n- Hilt\n- Coroutines + Flow\n- Firebase Authentication\n- Cloud Firestore\n- Navigation Compose\n- Glance widgets\n\n## Project structure\n\nMain source root:\n\n```text\napp/src/main/java/com/davideagostini/summ\n```\n\nTop-level packages:\n\n```text\nsumm/\n├── data/       # Firebase access, repositories, entities, session state, DI\n├── domain/     # Shared models and lightweight use cases\n├── tile/       # Quick Settings tile integration\n├── ui/         # Compose screens, ViewModels, state, feature components\n└── widget/     # Home-screen widgets and widget data sources\n```\n\nThe current app pattern is:\n\n```text\nScreen composable\n  -\u003e collects immutable state with collectAsStateWithLifecycle()\nViewModel\n  -\u003e exposes uiState + renderState\nRepository / Use Case\n  -\u003e reads and writes Firebase-backed data\n```\n\nApp text is resource-based and ready for Android per-app language switching through the system locale picker and the in-app language screen.\n\nComposable screens should stay focused on rendering and screen orchestration. Derived business data such as totals, grouped lists, chart models, and filtered lists should be prepared in `ViewModel` or shared model/use-case code.\n\n## Requirements\n\n- Android Studio\n- JDK 17\n- Android SDK\n- Firebase project\n\n## Backend setup required\n\nTo actually run the app, you need your own Firebase project.\n\nMinimum backend setup:\n\n- Firebase Authentication with Google sign-in enabled\n- Cloud Firestore created\n- `app/google-services.json` added locally\n- `firebase/firestore.rules` deployed\n- `firebase/firestore.indexes.json` deployed\n\nThe provided Firestore rules support the initial household bootstrap flow used by the Android app:\n- create household document\n- create the owner membership\n- seed default categories\n\nThis repository is app-first, but the Android client depends on that Firebase setup to work correctly.\n\n## Local setup\n\n### 1. Create a Firebase project\n\n- Open [Firebase Console](https://console.firebase.google.com/)\n- Create a new project\n\n### 2. Register the Android app\n\nUse this package name:\n\n```text\ncom.davideagostini.summ\n```\n\n### 3. Enable Google sign-in\n\n- Open `Authentication`\n- Enable `Google`\n- Set the support email if requested\n\n### 4. Create Firestore\n\n- Open `Firestore Database`\n- Create a database\n- Choose the mode you prefer for local development\n\n### 5. Add Android SHA fingerprints\n\nFrom the repository root:\n\n```bash\ncd mobile-app\n./gradlew signingReport\n```\n\nAdd the debug `SHA-1` and `SHA-256` fingerprints to the Android app in Firebase.\n\n### 6. Add `google-services.json`\n\nDownload the file from Firebase and place it here:\n\n```text\napp/google-services.json\n```\n\nThis file is intentionally ignored by Git.\n\n### 7. Deploy Firestore rules and indexes\n\nFrom the `mobile-app/firebase` folder:\n\n```bash\ncd mobile-app/firebase\nfirebase use --add\nfirebase deploy --only firestore:rules\nfirebase deploy --only firestore:indexes\n```\n\nIf you prefer, you can deploy with `--project \u003cyour-project-id\u003e` instead of setting an active project first.\n\n### 8. Build and install\n\n```bash\ncd mobile-app\n./gradlew assembleDebug\n./gradlew installDebug\n```\n\n## Firestore data model\n\nExpected structure:\n\n```text\nusers/{uid}\nhouseholds/{householdId}\nhouseholds/{householdId}/members/{userId}\nhouseholds/{householdId}/categories/{categoryId}\nhouseholds/{householdId}/transactions/{transactionId}\nhouseholds/{householdId}/assets/{assetId}\nhouseholds/{householdId}/assets/{assetId}/history/{entryId}\nhouseholds/{householdId}/recurringTransactions/{recurringTransactionId}\nhouseholds/{householdId}/monthCloses/{period}\nhouseholds/{householdId}/invites/{inviteId}\n```\n\n## Release signing\n\nCreate a local `keystore.properties` file by copying [`keystore.properties.example`](./keystore.properties.example) and filling in your local values.\n\nExample:\n\n```properties\nstoreFile=/absolute/path/to/your-upload-key.jks\nstorePassword=change-me\nkeyAlias=upload\nkeyPassword=change-me\n```\n\nBuild a release bundle with:\n\n```bash\ncd mobile-app\n./gradlew bundleRelease\n```\n\nThe output bundle will be generated under:\n\n```text\napp/build/outputs/bundle/release/app-release.aab\n```\n\n## GitHub release automation\n\nThis repository is set up so that pushing a tag like `v0.0.5` can:\n\n- build a signed release APK\n- build a signed release AAB\n- generate a release mapping file for deobfuscation\n- keep optional native debug metadata and symbol tables as workflow artifacts when available\n- publish both files to a GitHub Release\n\nRequired GitHub Actions secrets:\n\n- `ANDROID_KEYSTORE_BASE64`\n- `ANDROID_KEYSTORE_PASSWORD`\n- `ANDROID_KEY_ALIAS`\n- `ANDROID_KEY_PASSWORD`\n- `GOOGLE_SERVICES_JSON_BASE64`\n\nRelease notes:\n\n- CI validates that the decoded `google-services.json` matches `com.davideagostini.summ` and generates `default_web_client_id`\n- release builds explicitly keep `@string/default_web_client_id` so `shrinkResources` does not remove Google Sign-In configuration\n\nHow it works:\n\n1. Convert your keystore to base64 locally\n2. Store the value in `ANDROID_KEYSTORE_BASE64`\n3. Add the other signing values as repository secrets\n4. Push a tag such as:\n\n```bash\ngit tag v0.0.5\ngit push origin v0.0.5\n```\n\nThe workflow will decode the keystore, sign the release build, generate both `APK` and `AAB`, and attach them to the Dunio GitHub Release.\n\nRelease builds use minification and resource shrinking. The generated `mapping.txt` is uploaded as a GitHub Actions artifact so you can keep the deobfuscation file for Play Console or post-release analysis without exposing it in the public GitHub Release. Native debug metadata and symbol tables are also uploaded as optional workflow artifacts when AGP produces them.\n\n## Security and publishing notes\n\nDo not commit:\n\n- `app/google-services.json`\n- `local.properties`\n- `keystore.properties`\n- `.jks` / `.keystore` files\n- service account JSON files\n\nIf a local Firebase file was added to Git by mistake:\n\n```bash\ngit rm --cached app/google-services.json\n```\n\n## Documentation\n\n- [`CONTRIBUTING.md`](./CONTRIBUTING.md)\n- [`project_overview.md`](./project_overview.md)\n- [`FIRST_RELEASE_CHECKLIST.md`](./FIRST_RELEASE_CHECKLIST.md)\n- [Privacy Policy](https://dunio.app/privacy-policy)\n- [Terms of Service](https://dunio.app/terms-of-service)\n\n## Roadmap ideas\n\n### High Priority · Lower Effort\n\n- income vs expense analysis with category breakdown\n- improved home-screen widgets\n- user feedback mechanism\n\n### High Priority · Medium Effort\n\n- budgets with weekly, monthly, and yearly spending limits by category\n- reports and summaries for monthly review\n- notifications and reminders\n\n### Future Additions · Higher Effort\n\n- import transactions from CSV with validation\n- bank CSV import support\n- better backup and migration flows\n- Wear OS support\n- AI-powered finance features\n\n## Support the project\n\nDunio is free to use and open source. If you find it useful and want to support ongoing development, you can do it here:\n\n- [Buy Me a Coffee](https://buymeacoffee.com/davideagostini)\n- [GitHub Sponsors](https://github.com/sponsors/davideagostini)\n\n## Star History\n\nIf you find Dunio useful, consider giving the repository a star.\n\n[![Star History Chart](https://app.repohistory.com/api/svg?repo=davideagostini/dunio\u0026type=Date\u0026background=F9FAEF\u0026color=4C662B)](https://app.repohistory.com/star-history)\n\n## License\n\nThis repository uses the MIT license. See [`LICENSE`](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavideagostini%2Fdunio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavideagostini%2Fdunio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavideagostini%2Fdunio/lists"}