handleAuthenticated method
Public handler for auth state changes. Called when user authenticates.
This method can be passed to AuthService constructor for race-free initialization, ensuring callbacks are registered before Firebase listeners attach.
Usage
// Race-free initialization pattern:
final deviceService = DeviceServiceImpl();
final auth = AuthServiceImpl(
firebaseApp: app,
onAuthenticatedCallbacks: [deviceService.handleAuthenticated],
);
await deviceService.initialize(authService: auth);
Defensive Behavior
- Returns immediately if
uidis null (shouldn't happen in practice) - Logs a warning if called before initialize (indicates ordering bug)
- Uses pending payload fallback for graceful degradation
Parameters
uid: The authenticated user's ID, or null on logout.
Implementation
@override
Future<void> handleAuthenticated(String? uid) async {
// Defensive check - uid should never be null when called from AuthService,
// but guard against unexpected edge cases.
if (uid == null) {
logw('DeviceService: handleAuthenticated called with null uid, skipping');
return;
}
// Defensive check - warn if called before initialize().
// This can happen if initialize() awaits are executed sequentially rather than
// in parallel, allowing the auth callback to fire before all services are ready.
// The pending payload system provides graceful degradation, but this indicates
// an initialization ordering bug that should be fixed.
if (_authService == null) {
logw('DeviceService: handleAuthenticated called before initialize(). '
'Device registration will use pending payload fallback. '
'This indicates an initialization ordering issue - see Constraint 2 in plan.auth-race.md');
}
logd('DeviceService: handleAuthenticated called, uid=$uid');
await _flushPendingPayload(bypassBackoff: true);
await registerDevice();
}