Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Jay-byte389/AMS/llms.txt

Use this file to discover all available pages before exploring further.

All authentication side-effects in AMS are managed through async thunks created with Redux Toolkit’s createAsyncThunk. Each thunk lives in src/redux/thunk/authThunk.js and interacts with the src/services/storage.js layer to read and write session data from @react-native-async-storage/async-storage. The authSlice extra reducers respond to the pending, fulfilled, and rejected lifecycle actions of every thunk, keeping the Redux state in sync without any manual boilerplate.

Redux State Shape

FieldTypeDescription
userobject | nullThe currently logged-in user object
isAuthenticatedbooleantrue when a valid session is active
loadingbooleantrue during any in-flight async operation
errorstring | nullThe most recent error message, or null
loading is initialised to true (not false) so the app can display a splash/loading screen while checkAuthSession resolves on first launch without a flash of the unauthenticated UI.

Thunks

checkAuthSession

Reads the persisted session from storage and restores the user into Redux state. This is the very first thunk dispatched in the application — called inside a useEffect on mount in the root navigator.
Action typeauth/checkAuthSession
ParametersNone
Returns (fulfilled)UserObject | null — the stored user, or null if no session exists
Returns (rejected)rejectWithValue(error.message)
State effects
CaseloadinguserisAuthenticated
pendingtrue
fulfilled (user found)falseuser objecttrue
fulfilled (no session)falsenullfalse
rejectedfalse
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { checkAuthSession } from '../redux/thunk/authThunk';

export default function AppNavigator() {
  const dispatch = useDispatch();
  const { isAuthenticated, loading } = useSelector(state => state.auth);

  useEffect(() => {
    dispatch(checkAuthSession());
  }, []);

  if (loading) return <SplashScreen />;

  return isAuthenticated ? <AppStack /> : <AuthStack />;
}

signupUser

Registers a new user by persisting the account to local storage and immediately creating an active session for them.
Action typeauth/signupUser
Returns (fulfilled)The original userData object
Returns (rejected)rejectWithValue(result.error) from saveUser, or rejectWithValue(error.message) on unexpected throws
userData
object
required
The full user object to register. Must include at minimum email or mobile and password fields to allow future login via validateUser.
Execution flow
1

Save account

Calls saveUser(userData), which appends the new user to the @registered_users array in AsyncStorage. Returns { success: false, error } if storage fails.
2

Create session

On success, calls saveLoggedInUser(userData) to write the user under the @logged_in_user key, establishing an active session.
3

Return payload

Returns userData as the fulfilled payload, which the slice writes to state.user and sets state.isAuthenticated = true.
State effects
CaseloadinguserisAuthenticatederror
pendingtruenull
fulfilledfalseuserDatatrue
rejectedfalseerror string
import { useDispatch, useSelector } from 'react-redux';
import { signupUser } from '../redux/thunk/authThunk';

const dispatch = useDispatch();
const { loading, error } = useSelector(state => state.auth);

const handleSignup = async () => {
  const userData = {
    name: 'Jane Doe',
    email: 'jane@example.com',
    mobile: '0712345678',
    password: 'securepassword',
  };

  const result = await dispatch(signupUser(userData));

  if (signupUser.fulfilled.match(result)) {
    // navigation happens automatically via AppNavigator's isAuthenticated check
  }
};

loginUser

Validates an existing user’s credentials against local storage and, on success, persists the session.
Action typeauth/loginuser
Returns (fulfilled)UserObject — the matched user from storage
Returns (rejected)rejectWithValue(result.error) on credential mismatch, or rejectWithValue(error.message) on unexpected throws
The action type string is 'auth/loginuser' (all-lowercase user) — note the inconsistency with signupUser and logoutUser. Use the exported thunk reference directly rather than matching on the string literal to avoid typos.
emailOrPhone
string
required
The email address or mobile number used during registration. Passed directly to validateUser() in the storage service.
password
string
required
The plaintext password to check against the stored user record.
Execution flow
1

Validate credentials

Calls validateUser(emailOrPhone, password). Returns { success: false, error } if the user is not found or the password does not match.
2

Persist session

On success, calls saveLoggedInUser(result.user) to write the session under @logged_in_user.
3

Return payload

Returns result.user as the fulfilled payload.
State effects
CaseloadinguserisAuthenticatederror
pendingtruenull
fulfilledfalseuser objecttrue
rejectedfalseerror string
import { useDispatch, useSelector } from 'react-redux';
import { loginUser } from '../redux/thunk/authThunk';
import { clearAuthError } from '../redux/slices/authSlice';

const dispatch = useDispatch();
const { loading, error } = useSelector(state => state.auth);

const handleLogin = async () => {
  dispatch(clearAuthError());

  const result = await dispatch(
    loginUser({ emailOrPhone: 'jane@example.com', password: 'securepassword' })
  );

  if (loginUser.rejected.match(result)) {
    // result.payload contains the error string from rejectWithValue
    console.warn('Login failed:', result.payload);
  }
};

logoutUser

Ends the current session by removing @logged_in_user from AsyncStorage and resetting auth state.
Action typeauth/logoutUser
ParametersNone
Returns (fulfilled)true
State effects
CaseuserisAuthenticatedloading
fulfillednullfalsefalse
Only the fulfilled case updates state. If logoutUserStorage() throws, the error is caught internally. The session key is always removed before any Redux state changes occur.
import { useDispatch } from 'react-redux';
import { logoutUser } from '../redux/thunk/authThunk';

const dispatch = useDispatch();

const handleLogout = () => {
  dispatch(logoutUser());
  // AppNavigator's isAuthenticated selector will redirect to AuthStack
};

Synchronous Actions

clearAuthError

Resets state.error to null. Dispatch this before a new login or signup attempt to clear any previous error message from the UI.
import { clearAuthError } from '../redux/slices/authSlice';

dispatch(clearAuthError());

Build docs developers (and LLMs) love