App
Petfolio
Cross-Platform Pet Care App
Screenshots
Overview
Petfolio is a cross-platform mobile application that lets multiple caregivers share responsibility for a pet's routine — feeding schedules, medication reminders, vet records, and care handoffs — without coordination falling apart over text messages or verbal agreements.
The app runs on both iOS and Android from a single Flutter codebase, with Firebase providing real-time data synchronization so that a change made by one caregiver is immediately visible to all others.
Problem
Pet care shared across multiple people — partners, family members, pet sitters — frequently breaks down at the coordination layer. Who fed the dog this morning? Did anyone give the cat her medication? These questions arise not from negligence but from the absence of a shared, reliable source of truth.
Existing pet apps are typically single-user or treat sharing as an afterthought. Petfolio was designed with multi-caregiver coordination as the core use case from the start, which shaped every data modeling and access control decision.
Approach
The most architecturally significant decision was Firestore data modeling. I structured the schema around explicit ownership: each pet document has a primary owner and a list of authorized caregivers, and security rules enforce that mutations require appropriate role membership. This prevents unauthorized writes at the database layer, not just the application layer.
State management uses Riverpod, which allowed me to keep the UI layer declarative and reactive without tight coupling to Firebase directly. Repository classes own the Firestore interaction; the UI consumes providers that expose clean, typed state. This pattern made the codebase significantly easier to test than direct Firestore access scattered through widget trees.
For notifications, I integrated local timezone-aware reminders that calculate next-fire times based on the device's local timezone rather than UTC. This prevents the common drift problem where a 7am reminder actually fires at 7am UTC after a daylight saving transition.
Tech Stack
| Technology | Rationale |
|---|---|
| Flutter / Dart | Single codebase for iOS and Android with near-native performance; strong widget composability for complex UI state. |
| Firebase Firestore | Real-time synchronization across devices; security rules enable database-level access control without a custom backend. |
| Firebase Auth | Handles user identity and session management; integrates cleanly with Firestore security rule UID matching. |
| Riverpod | Scoped, testable state management; providers decouple UI from data sources and support clear separation of concerns. |
Key Decisions & Tradeoffs
Firebase vs. custom backend. Using Firebase eliminated the need to build and maintain a server, which was the right call for a project of this scope. The tradeoff is that complex queries are constrained by Firestore's query model — I had to design the data schema with query patterns in mind rather than normalizing freely. For the current feature set, this constraint was manageable.
Riverpod over BLoC or Provider. I chose Riverpod for its explicit dependency declaration and compile-time safety. BLoC would have introduced more boilerplate for modest complexity; the basic Provider package lacks the scoping control needed for multi-pet, multi-caregiver state. Riverpod hit the balance well for this project.
What I Learned
- Data modeling in Firestore is fundamentally about query design, not normalization. Designing the schema first and then testing it against all anticipated read patterns saved significant restructuring later.
- Riverpod's provider scoping becomes genuinely valuable — not just stylistically cleaner — once you have state that varies per entity (per pet, per user role). Building with scoped providers from the start paid off when adding multi-pet support.
- Timezone handling in local notifications is underspecified by most libraries' documentation. Testing against simulated timezone changes early exposed bugs that would have been very difficult to reproduce in production.