Reusable React Native package for fetching TDMU university schedules with Google authentication
npm install react-native-t-scheduleReusable React Native package for fetching TDMU (Thủ Dầu Một University) schedules with Google authentication using Expo AuthSession.
✅ Easy Integration - Simple to integrate into any React Native project
✅ Expo AuthSession - Modern OAuth authentication without Google Cloud Console requirements
✅ Dynamic Client ID - Automatically fetches Google OAuth config from TDMU
✅ Automatic Caching - Built-in caching to reduce API calls
✅ TypeScript Support - Full TypeScript definitions included
✅ Flexible Usage - Use as a component, hook, or direct client
✅ Customizable UI - Fully customizable schedule rendering
> 🇻🇳 Vietnamese Guide: Hướng dẫn Best Fix (Tiếng Việt)
``bash`
npm install react-native-t-scheduleor
yarn add react-native-t-schedule
This package requires the following peer dependencies:
`bash`
npm install @react-native-async-storage/async-storage axios expo-auth-session expo-web-browser expo-cryptoor
yarn add @react-native-async-storage/async-storage axios expo-auth-session expo-web-browser expo-crypto
If you're using Expo, update your app.json:
`json`
{
"expo": {
"name": "your-app",
"scheme": "your-app-scheme",
"plugins": ["expo-router"]
}
}
This package uses Expo AuthSession with TDMU's public Google OAuth configuration, so you don't need to:
- ❌ Set up Google Cloud Console project
- ❌ Configure OAuth consent screen
- ❌ Add SHA-1 fingerprints
- ❌ Create Android/iOS Client IDs
- ❌ Manage OAuth credentials
The authentication flow automatically uses the university's Google OAuth settings.
📖 Read the Complete Expo AuthSession Setup Guide
#### iOS & Android
No additional setup required! Expo AuthSession handles all native configuration automatically.
The simplest way to integrate TDMU schedule fetching:
`typescript
import React from 'react';
import { SafeAreaView } from 'react-native';
import { TDMUScheduleView } from 'react-native-t-schedule';
export default function App() {
return (
);
}
`
#### With Configuration
`typescript
import { TDMUScheduleView } from 'react-native-t-schedule';
import type { ScheduleItem, Semester } from 'react-native-t-schedule';
function App() {
const handleScheduleFetched = (schedule: ScheduleItem[], semester: Semester | null) => {
console.log('Schedule fetched!', schedule.length, 'items');
};
return (
tdmuUsername: 'user@gw',
cacheEnabled: true,
cacheDuration: 3600000, // 1 hour
}}
onScheduleFetched={handleScheduleFetched}
/>
);
}
`
#### With Custom Rendering
`typescript
import { View, Text } from 'react-native';
import { TDMUScheduleView } from 'react-native-t-schedule';
import type { ScheduleItem } from 'react-native-t-schedule';
function App() {
const renderScheduleItem = ({ item }: { item: ScheduleItem }) => (
);
return (
);
}
`
For more control over the authentication and fetching process:
`typescript
import React from 'react';
import { View, Text, Button, FlatList } from 'react-native';
import { useTDMUSchedule } from 'react-native-t-schedule';
function MyScheduleScreen() {
const {
isAuthenticated,
isLoading,
schedule,
semester,
error,
authenticate,
fetchSchedule,
logout,
} = useTDMUSchedule({
tdmuUsername: 'user@gw',
cacheEnabled: true,
});
if (!isAuthenticated) {
return (
);
}
if (error) {
return
}
if (isLoading) {
return
}
return (
renderItem={({ item }) => (
)}
/>
);
}
`
For complete control over the authentication flow:
`typescript
import { TDMUScheduleClient } from 'react-native-t-schedule';
import * as AuthSession from 'expo-auth-session';
import axios from 'axios';
async function fetchMySchedule() {
const client = new TDMUScheduleClient({
tdmuUsername: 'user@gw',
cacheEnabled: true,
cacheDuration: 3600000,
});
try {
// 1️⃣ Get Google client ID from TDMU
const { data } = await axios.get('https://dkmh.tdmu.edu.vn/authconfig');
const clientId = data.gg;
// 2️⃣ Start Google OAuth flow
const redirectUri = AuthSession.makeRedirectUri({ useProxy: true });
const authUrl =
https://accounts.google.com/o/oauth2/v2/auth? +response_type=id_token&
+scope=openid%20email%20profile&
+client_id=${clientId}&
+redirect_uri=${encodeURIComponent(redirectUri)}&
+nonce=${Math.random().toString(36).substring(2)}
;
const result = await AuthSession.startAsync({ authUrl });
if (result.type !== 'success') {
throw new Error('Login cancelled');
}
const idToken = result.params.id_token;
// 3️⃣ Authenticate with TDMU using Google ID token
await client.authenticateWithGoogle(idToken);
// Fetch current schedule
const scheduleResult = await client.fetchCurrentSchedule();
console.log('Schedule:', scheduleResult.schedule);
console.log('Semester:', scheduleResult.semester);
return scheduleResult;
} catch (error) {
console.error('Error:', error);
}
}
`
#### Constructor
`typescript`
new TDMUScheduleClient(config?: TDMUConfig)
Config Options:
- baseURL (string): TDMU API base URL. Default: 'https://dkmh.tdmu.edu.vn/api'tdmuUsername
- (string): TDMU username. Default: 'user@gw'cacheEnabled
- (boolean): Enable caching. Default: truecacheDuration
- (number): Cache duration in ms. Default: 3600000 (1 hour)
#### Methods
##### authenticateWithGoogle(googleIdToken: string): Promise
Authenticate with TDMU using Google ID token.
##### getAuthConfig(): Promise<{ gg: string; logoff: boolean; timeout: number }>
Get TDMU authentication configuration including Google client ID.
##### validateAccess(): Promise
Validate user's access to TDMU functions.
##### getSemesters(): Promise
Get list of available semesters.
##### getSchedule(semesterId: string | number, userId?: string): Promise
Get schedule for a specific semester.
##### fetchCurrentSchedule(): Promise
Fetch schedule for the current semester (complete flow).
##### clearCache(): Promise
Clear all cached data.
##### logout(): Promise
Logout and clear all data.
---
`typescript`
const {
isAuthenticated,
isLoading,
schedule,
semester,
error,
authenticate,
fetchSchedule,
fetchScheduleForSemester,
fetchSemesters,
logout,
clearCache
} = useTDMUSchedule(config?: TDMUConfig);
Returns:
State:
- isAuthenticated (boolean): Authentication statusisLoading
- (boolean): Loading stateschedule
- (ScheduleItem[] | null): Schedule datasemester
- (Semester | null): Current semester infoerror
- (string | null): Error message
Actions:
- authenticate(): Authenticate with GooglefetchSchedule()
- : Fetch current schedulefetchScheduleForSemester(semesterId)
- : Fetch specific semesterfetchSemesters()
- : Get available semesterslogout()
- : Logout userclearCache()
- : Clear cached data
---
`typescript`
onScheduleFetched?: (schedule: ScheduleItem[], semester: Semester | null) => void
renderScheduleItem?: (info: { item: ScheduleItem }) => React.ReactElement
style?: ViewStyle
/>
Props:
- config: Configuration options (same as TDMUScheduleClient)onScheduleFetched
- : Callback when schedule is fetchedrenderScheduleItem
- : Custom render function for schedule itemsstyle
- : Custom container style
`typescript`
interface ScheduleItem {
id?: string;
maMon?: string; // Course code
courseCode?: string;
tenMon?: string; // Course name
courseName?: string;
thu?: string; // Day of week
dayOfWeek?: string;
tiet?: string; // Period
period?: string;
phong?: string; // Room
room?: string;
giangVien?: string; // Instructor
instructor?: string;
}
`typescript`
interface Semester {
id?: string;
hocKyId?: string;
tenHocKy?: string; // Semester name
semesterName?: string;
}
`typescript`
interface ScheduleResult {
semester: Semester;
schedule: ScheduleItem[];
fetchedAt: string; // ISO timestamp
}
Check the /example directory for complete working examples:
- BasicExample.tsx - Simple component usage
- HookExample.tsx - Using the hook
- CustomRenderExample.tsx - Custom rendering
- DirectClientExample.tsx - Direct client usage
Solution: Ensure Google Access Token is valid and not expired. Check your Google Sign-In configuration.
Solution: Verify the user has access to the TDMU system and is properly authenticated.
Solution: Check AsyncStorage permissions and storage availability on the device.
Solution: Verify webClientId` in GoogleSignin.configure() and ensure Firebase setup is correct.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT
TrungDev - GitHub
This package is designed to work with the TDMU (Thủ Dầu Một University) academic system.