162 lines
5.0 KiB
Markdown
162 lines
5.0 KiB
Markdown
# Auto-Login Fix - Token Persistence Issue
|
|
|
|
## Problem
|
|
User reported that after "clearing the app", they were logged out and had to re-enter phone number and OTP to sign in.
|
|
|
|
## Root Cause Analysis
|
|
|
|
### What "Clearing the App" Means
|
|
There are different ways to "clear" an app in Android:
|
|
|
|
1. **Force Stop** (Settings → Apps → [App] → Force Stop)
|
|
- ✅ **Expected**: Tokens should persist
|
|
- Tokens stored in EncryptedSharedPreferences should remain
|
|
|
|
2. **Clear App Data** (Settings → Apps → [App] → Storage → Clear Data)
|
|
- ⚠️ **Expected**: Tokens will be deleted
|
|
- This deletes ALL app data including EncryptedSharedPreferences
|
|
- User will need to sign in again (this is normal Android behavior)
|
|
|
|
3. **Uninstall/Reinstall**
|
|
- ⚠️ **Expected**: Tokens will be deleted
|
|
- User will need to sign in again
|
|
|
|
4. **Close/Reopen App** (Normal usage)
|
|
- ✅ **Expected**: Tokens should persist
|
|
- User should remain logged in
|
|
|
|
### Issues Found
|
|
|
|
1. **Network Errors Clearing Tokens**
|
|
- **Problem**: If there was a network error during token validation, tokens were being cleared
|
|
- **Impact**: User would be logged out even if tokens were still valid
|
|
- **Fix**: Distinguish between network errors and authentication errors
|
|
|
|
2. **Token Save Timing**
|
|
- **Problem**: Using `.apply()` for token storage (asynchronous)
|
|
- **Impact**: Tokens might not be saved immediately before app closes
|
|
- **Fix**: Changed to `.commit()` for synchronous save (ensures tokens are saved)
|
|
|
|
## Fixes Applied
|
|
|
|
### 1. Improved Error Handling in MainViewModel
|
|
**File**: `MainViewModel.kt`
|
|
|
|
**Changes**:
|
|
- Added network error detection
|
|
- Only clear tokens on authentication errors, not network errors
|
|
- Better error messages for users
|
|
|
|
**Logic**:
|
|
```kotlin
|
|
if (isNetworkError) {
|
|
// Don't clear tokens - they might still be valid
|
|
// User might be offline
|
|
return@launch
|
|
}
|
|
```
|
|
|
|
### 2. Synchronous Token Saving
|
|
**File**: `TokenManager.kt`
|
|
|
|
**Changes**:
|
|
- Changed from `.apply()` to `.commit()` for token saving
|
|
- Ensures tokens are saved synchronously before app closes
|
|
|
|
**Before**:
|
|
```kotlin
|
|
.apply() // Asynchronous - might not complete before app closes
|
|
```
|
|
|
|
**After**:
|
|
```kotlin
|
|
.commit() // Synchronous - ensures tokens are saved immediately
|
|
```
|
|
|
|
## How It Works Now
|
|
|
|
### Normal App Usage (Close/Reopen)
|
|
1. User signs in → Tokens saved to EncryptedSharedPreferences
|
|
2. User closes app → Tokens remain in storage
|
|
3. User reopens app → `MainViewModel.init()` checks for tokens
|
|
4. If tokens exist → Validates tokens
|
|
5. If tokens valid → User automatically logged in ✅
|
|
6. If tokens expired → Attempts refresh
|
|
7. If refresh succeeds → User logged in ✅
|
|
8. If refresh fails → User needs to sign in again
|
|
|
|
### Network Error Handling
|
|
1. App starts → Checks for tokens
|
|
2. Network error occurs → **Tokens NOT cleared**
|
|
3. User sees "Network error" message
|
|
4. When network available → Tokens still valid, user can retry
|
|
|
|
### Authentication Error Handling
|
|
1. App starts → Checks for tokens
|
|
2. Authentication error (401, invalid token) → **Tokens cleared**
|
|
3. User needs to sign in again
|
|
|
|
## Testing Scenarios
|
|
|
|
### ✅ Should Keep User Logged In
|
|
- Close app normally and reopen
|
|
- Force stop app and reopen
|
|
- Restart phone and reopen app
|
|
- Network error during token validation (tokens preserved)
|
|
|
|
### ⚠️ Will Log User Out (Expected Behavior)
|
|
- Clear app data from Android settings
|
|
- Uninstall and reinstall app
|
|
- Refresh token expired (7 days of inactivity)
|
|
- Authentication error (invalid/expired tokens)
|
|
|
|
## Important Notes
|
|
|
|
1. **Clearing App Data**: If user clears app data from Android settings, tokens will be deleted. This is **expected Android behavior** - clearing app data removes all stored data.
|
|
|
|
2. **Token Expiration**:
|
|
- Access tokens: 15 minutes
|
|
- Refresh tokens: 7 days (with activity)
|
|
- If refresh token expires, user must sign in again
|
|
|
|
3. **Network Errors**: Network errors no longer cause tokens to be cleared. User will see an error message but tokens remain valid.
|
|
|
|
## User Experience
|
|
|
|
### Before Fix
|
|
- ❌ Network errors could log user out
|
|
- ❌ Tokens might not be saved if app closed quickly
|
|
- ❌ Unclear error messages
|
|
|
|
### After Fix
|
|
- ✅ Network errors don't log user out
|
|
- ✅ Tokens saved synchronously (guaranteed)
|
|
- ✅ Clear error messages (network vs auth errors)
|
|
- ✅ Better user experience
|
|
|
|
## Debugging
|
|
|
|
To check if tokens are being saved:
|
|
1. Sign in to the app
|
|
2. Check logs for "User authenticated successfully"
|
|
3. Close app completely
|
|
4. Reopen app
|
|
5. Check logs for token validation
|
|
|
|
If tokens are missing:
|
|
- Check if app data was cleared
|
|
- Check if refresh token expired
|
|
- Check logs for authentication errors
|
|
|
|
## Summary
|
|
|
|
The fix ensures:
|
|
1. ✅ Tokens persist when app is closed/reopened normally
|
|
2. ✅ Network errors don't clear tokens
|
|
3. ✅ Tokens are saved synchronously
|
|
4. ✅ Better error handling and user feedback
|
|
5. ✅ Clear distinction between network and auth errors
|
|
|
|
**Note**: If user clears app data from Android settings, they will need to sign in again. This is normal Android behavior and cannot be prevented.
|
|
|