Problem
When a user reinstalls the app on a new device (or after clearing data), the app checks the backend for onboarding completion status via GET /v1/users/onboarding. If the backend returns completed: true, the app sets the local onboardingCompleted flag and routes directly to HomePageWrapper, completely skipping the onboarding flow — including Step 4 (Permissions).
This means the following permissions are never requested on the fresh install:
- Notifications (Android & iOS)
- Location — When In Use + Always (Android & iOS)
- Background Activity / Battery Optimization (Android only)
Impact
- Features that depend on these permissions silently fail or degrade
- Location-based features don't work
- Notifications are never received
- On Android, background processing may be killed by the OS
Root Cause
The routing logic in lib/mobile/mobile_app.dart:20 is binary:
if (SharedPreferencesUtil().onboardingCompleted) {
return const HomePageWrapper(); // Skip everything
} else {
return const OnboardingWrapper(); // Full onboarding
}
And the restoration in lib/services/auth_service.dart:463-490 sets onboardingCompleted = true from the backend without checking whether local permissions have been granted.
Relevant Code
| File |
Role |
app/lib/main.dart:195-199 |
Calls restoreOnboardingState() on startup |
app/lib/services/auth_service.dart:463-490 |
Fetches backend onboarding state, sets local flag |
app/lib/mobile/mobile_app.dart:20 |
Routes based on onboardingCompleted |
app/lib/pages/onboarding/wrapper.dart |
11-step onboarding (permissions are step 4) |
app/lib/pages/onboarding/permissions/permissions_widget.dart |
Permission request UI |
app/lib/providers/onboarding_provider.dart |
Permission check/request logic |
Suggested Solution
After restoring onboarding state from the backend on a fresh install, check whether critical permissions (notifications, location, bluetooth) are actually granted on the device. If not, show a dedicated permissions screen before routing to HomePageWrapper.
This could be:
- A lightweight permissions-only screen — not the full onboarding, just the permission requests from Step 4, shown as an interstitial before home
- Routing to just Step 4 of onboarding — reuse the existing
PermissionsWidget but skip all other steps
- A post-login permission check — in
HomePageWrapper init, check permissions and show a modal/bottom sheet if critical ones are missing
Option 1 or 2 is preferred since requesting permissions at app launch (right after login) has higher grant rates than deferred requests.
Implementation Notes
OnboardingProvider.updatePermissions() already has logic to check all platform permissions — reuse this
- The existing
PermissionsWidget can potentially be extracted/reused outside the full onboarding wrapper
- Consider persisting a local
permissionsGranted flag separate from onboardingCompleted so the check only runs once per install
- The check should be platform-aware (different permissions for Android vs iOS)
Problem
When a user reinstalls the app on a new device (or after clearing data), the app checks the backend for onboarding completion status via
GET /v1/users/onboarding. If the backend returnscompleted: true, the app sets the localonboardingCompletedflag and routes directly toHomePageWrapper, completely skipping the onboarding flow — including Step 4 (Permissions).This means the following permissions are never requested on the fresh install:
Impact
Root Cause
The routing logic in
lib/mobile/mobile_app.dart:20is binary:And the restoration in
lib/services/auth_service.dart:463-490setsonboardingCompleted = truefrom the backend without checking whether local permissions have been granted.Relevant Code
app/lib/main.dart:195-199restoreOnboardingState()on startupapp/lib/services/auth_service.dart:463-490app/lib/mobile/mobile_app.dart:20onboardingCompletedapp/lib/pages/onboarding/wrapper.dartapp/lib/pages/onboarding/permissions/permissions_widget.dartapp/lib/providers/onboarding_provider.dartSuggested Solution
After restoring onboarding state from the backend on a fresh install, check whether critical permissions (notifications, location, bluetooth) are actually granted on the device. If not, show a dedicated permissions screen before routing to
HomePageWrapper.This could be:
PermissionsWidgetbut skip all other stepsHomePageWrapperinit, check permissions and show a modal/bottom sheet if critical ones are missingOption 1 or 2 is preferred since requesting permissions at app launch (right after login) has higher grant rates than deferred requests.
Implementation Notes
OnboardingProvider.updatePermissions()already has logic to check all platform permissions — reuse thisPermissionsWidgetcan potentially be extracted/reused outside the full onboarding wrapperpermissionsGrantedflag separate fromonboardingCompletedso the check only runs once per install