A modern authentication application built with Expo, featuring a complete authentication flow using Firebase as the backend service.
- 🔒 Complete authentication flow
- User sign-in
- User registration
- Secure session management
- Logout functionality
- 📱 Modern UI with Tailwind CSS
- 🎯 TypeScript for type safety
- 📁 Organized file structure with Expo Router
- 🔄 Context-based state management
app/
├── (app)/ # Protected app routes
│ ├── (drawer)/ # Drawer navigation
│ │ └── (tabs)/ # Tab navigation
│ │ └── index.tsx # Home screen
│ └── _layout.tsx # App layout with auth protection
├── sign-in.tsx # Sign in screen
├── sign-up.tsx # Sign up screen
└── _layout.tsx # Root layout
-
Clone the repository
git clone [repository-url]
-
Install dependencies
yarn
-
Set up environment variables Create a
.env
file with your Firebase credentials:EXPO_PUBLIC_FIREBASE_API_KEY= EXPO_PUBLIC_FIREBASE_PROJECT_ID=
-
Start the development server
npx expo start
The project uses a custom Metro configuration to support both Firebase Auth and NativeWind (Tailwind CSS). Here's the setup in metro.config.js
:
const { getDefaultConfig } = require("@expo/metro-config");
const { withNativeWind } = require("nativewind/metro");
const config = getDefaultConfig(__dirname);
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = withNativeWind(config, { input: "./global.css" });
This configuration:
- Adds support for Firebase's CommonJS modules
- Integrates NativeWind for Tailwind CSS support
- Extends source extensions to include "mjs" and "cjs" files
Firebase Auth is configured with React Native persistence for maintaining authentication state:
import { initializeApp } from "firebase/app";
import { initializeAuth, getAuth } from "firebase/auth";
import AsyncStorage from "@react-native-async-storage/async-storage";
// IGNORE IMPORT ERROR, this is a valid import, still investigating
import { getReactNativePersistence } from "firebase/auth/dist/rn/persistence";
// Initialize Firebase with persistence
let auth;
try {
auth = getAuth();
} catch {
auth = initializeAuth(app, {
persistence: getReactNativePersistence(AsyncStorage),
});
}
- Frontend Framework: Expo/React Native
- Styling: Tailwind CSS (via NativeWind)
- Navigation: Expo Router
- Backend: Firebase
- Language: TypeScript
- State Management: React Context
- Authentication Context: Manages user session state and auth operations
- Protected Routes: Automatic redirection for unauthenticated users
- Drawer Navigation: Side menu for app navigation
- Tab Navigation: Bottom tabs for main app sections
To start developing:
-
Run the development server:
npx expo start
-
Choose your preferred development environment:
- Press
i
for iOS simulator - Press
a
for Android emulator - Scan QR code with Expo Go app for physical device
- Press
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.