Dual-Role Management
RideEase is designed with a dual-role architecture that distinguishes between Riders and Drivers at the point of authentication. This ensures that users access the specific features and interface associated with their chosen account type.
Role Selection
During both the registration and login processes, users must explicitly select their role. This selection determines how the authentication request is processed and validated against the database.
Account Creation (Sign-Up)
When a user creates an account, the userType is persisted in the Firestore users collection. This role is permanent for that account and defines the permissions and UI flow the user will encounter.
// Example: Triggering sign-up with a specific role
String selectedUserType = "rider"; // or "driver"
authViewModel.signUpWithEmail(email, password, selectedUserType);
Authentication Logic
The AuthViewModel handles the creation of the user record in Firebase Auth and simultaneously creates a document in Firestore containing the userType.
| Parameter | Type | Description |
| :--- | :--- | :--- |
| email | String | The user's unique email address. |
| password | String | Account password (min. 6 characters). |
| userType | String | Must be exactly "rider" or "driver". |
Role Validation
To maintain system integrity, RideEase implements strict validation during the sign-in process. If a user registered as a Driver attempts to log in via the Rider portal, the system will block access.
Sign-In Enforcement
The signInWithEmail method compares the selectedUserType from the UI with the storedUserType fetched from Firestore.
// Example: Sign-in validation logic
viewModel.signInWithEmail(email, password, "driver");
// If the account in Firestore is marked as "rider",
// the ViewModel returns an error: "Wrong category selected"
Verification Utility
The AuthUtils class provides a helper method to validate role consistency, which is particularly useful during auto-login or session restoration.
AuthUtils.isUserTypeValid(context, userId, selectedUserType, new AuthUtils.UserDetailsCallback() {
@Override
public void onComplete(boolean isValid, String userId) {
if (isValid) {
// Proceed to MainActivity
} else {
// Force logout and show error
}
}
@Override
public void onError(String error) {
// Handle network/database errors
}
});
User Model Reference
The User model stores the role in a dedicated field. This is used throughout the application to toggle role-specific functionality (e.g., "Request a Ride" for Riders vs. "Go Online" for Drivers).
public class User {
private String userId;
private String userType; // "rider" or "driver"
// ... other fields
public String getUserType() { return userType; }
}
UI Implementation Guidelines
When building screens that involve role selection (like LoginActivity or SignupActivity), use the following state management pattern:
- Toggle State: Maintain a local variable (e.g.,
selectedUserType) that defaults to"rider". - Visual Feedback: Update the UI buttons to reflect the active selection.
- ViewModel Sync: Pass the active selection to the
AuthViewModelmethods.
// Logic for role selection buttons in Activity
binding.riderButton.setOnClickListener(v -> {
selectedUserType = "rider";
binding.riderButton.setSelected(true);
binding.driverButton.setSelected(false);
});
binding.driverButton.setOnClickListener(v -> {
selectedUserType = "driver";
binding.driverButton.setSelected(true);
binding.riderButton.setSelected(false);
});