Skip to content

benedictfred/save-it-mobile

Repository files navigation

Save It Mobile

Save It Mobile is a React Native fintech client built with Expo and Expo Router. It provides authentication, account verification, transfers, transaction history, notifications, profile/security settings, and Google sign-in.

Tech Stack

  • Expo SDK 54, React Native 0.81, React 19
  • Expo Router (file-based routing)
  • React Query for server state
  • React Hook Form + Zod for validation
  • NativeWind (Tailwind for React Native)
  • Axios for API integration
  • Firebase Authentication + Google Sign-In
  • Expo Secure Store for token persistence
  • Expo Notifications + Ably for real-time updates

Features

  • Email/password sign-up and login
  • Google authentication
  • Email verification flow (OTP)
  • Forgot password, OTP validation, and password reset
  • Transfer flow with confirmation and PIN validation
  • First-time transaction PIN setup (4-digit)
  • Change password and change transaction PIN
  • Transaction history and transaction receipt screen
  • Notification stream integration
  • Profile and security screens

Project Structure

app/
   (auth)/                 # Login, signup, forgot/reset flows
   (verification)/         # Email verification flow
   (app)/                  # Main authenticated app routes
      (tabs)/               # Home, history, profile tabs
components/               # Reusable UI and form components
contexts/                 # Auth context and app-wide providers
hooks/                    # Query/mutation and utility hooks
lib/                      # Axios, Firebase, schemas, utilities
services/                 # API request functions
types/                    # Shared TypeScript types

Prerequisites

  • Node.js 20+
  • pnpm (recommended in this repo) or npm
  • Android Studio and/or Xcode for native builds
  • EAS CLI (for cloud builds): npm i -g eas-cli

Environment Variables

Create a .env file in the project root with the following keys:

EXPO_PUBLIC_BASE_API_URL=
EXPO_PUBLIC_FIREBASE_API_KEY=
EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN=
EXPO_PUBLIC_FIREBASE_PROJECT_ID=
EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET=
EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
EXPO_PUBLIC_FIREBASE_APP_ID=
EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID=
EXPO_PUBLIC_WEB_CLIENT_ID=
EXPO_PUBLIC_IOS_CLIENT_ID=

Notes:

  • Android emulator commonly uses 10.0.2.2 for local backend access.
  • For a physical device, use your machine LAN IP for the API URL.

Installation

pnpm install

Running the App

Development server

pnpm start

Native run (local prebuild workflow)

pnpm android
pnpm ios

Web

pnpm web

Google Sign-In Notes

This project uses @react-native-google-signin/google-signin, which requires a native binary containing the module.

  • Use a development build or a custom native build.
  • Expo Go may not include all required native modules for this flow.
  • If Google Sign-In is unavailable in the binary, the app now lazy-loads the module and fails gracefully at button press time instead of crashing route registration.

Authentication and Routing

  • Route groups:
    • app/(auth) for unauthenticated routes
    • app/(verification) for pending verification users
    • app/(app) for active authenticated users
  • Root guard logic is implemented in app/_layout.tsx using token + user status.

Scripts

  • pnpm start - start Expo dev server
  • pnpm android - run Android native build
  • pnpm ios - run iOS native build
  • pnpm web - run web target
  • pnpm lint - lint project

Build and Release (EAS)

This repo includes eas.json profiles:

  • development (development client, internal distribution)
  • preview (internal distribution)
  • production (Android APK)

Example commands:

eas build --platform android --profile development
eas build --platform android --profile production
eas build --platform ios --profile preview

API Contract Quick Reference

Base URL is configured through EXPO_PUBLIC_BASE_API_URL.

All payloads below reflect the current frontend service layer usage in services/auth-service.ts and services/transaction-service.ts.

Authentication

  • POST /auth/signup
    • Request:
      {
        "name": "Jane Doe",
        "email": "jane@example.com",
        "password": "password123",
        "confirmPassword": "password123",
        "client": "mobile"
      }
  • POST /auth/login
    • Request:
      {
        "email": "jane@example.com",
        "password": "password123"
      }
  • POST /auth/google
    • Request:
      {
        "idToken": "<firebase-id-token>"
      }

Verification and Recovery

  • POST /auth/resend-verification-email
    • Request:
      {
        "client": "mobile"
      }
  • POST /auth/verify-email
    • Request:
      {
        "token": "123456"
      }
  • POST /auth/forgot-password
    • Request:
      {
        "email": "jane@example.com",
        "client": "mobile"
      }
  • POST /auth/validate-otp
    • Request:
      {
        "otp": "123456"
      }
  • POST /auth/reset-password
    • Request:
      {
        "password": "newPassword123",
        "token": "<reset-session-token>"
      }

Security Settings

  • PATCH /auth/update-password
    • Request:
      {
        "currentPassword": "oldPassword123",
        "newPassword": "newPassword123"
      }
  • PATCH /auth/pin
    • Request:
      {
        "pin": "1234"
      }
  • PATCH /auth/update-pin
    • Request:
      {
        "currentPin": "1234",
        "newPin": "5678"
      }

User and Transactions

  • GET /users/dashboard
    • Returns current user profile, account details, status, and related dashboard resources.
  • POST /transactions/transfer
    • Request:
      {
        "recipientAccNumber": "1234567890",
        "amount": 2500,
        "pin": "1234"
      }
  • PATCH /users/push-token
    • Request:
      {
        "pushToken": "ExponentPushToken[...]"
      }

Auth Header

  • Endpoints that require authentication use:
    • Authorization: Bearer <token>
  • Token injection and 401 handling are managed centrally in lib/axios.ts.

Troubleshooting

RNGoogleSignin could not be found

  • Cause: running a binary without the native Google Sign-In module.
  • Fix: run with a development/custom build that includes @react-native-google-signin/google-signin.

Expo Router warning: No route named "login" exists

  • Usually a symptom of module load failure in files imported by the route.
  • Fix the underlying runtime import error (for example native module issues), then restart the bundler.

401 token expiration logs

  • Expected when a token is invalid/expired.
  • Axios interceptor logs out and redirects via auth guards.

Security Notes

  • Do not commit private API secrets.
  • Public Expo/Firebase client values are expected in frontend builds, but server secrets must stay on backend infrastructure.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages