A complete, fully functional web-based attendance system that combines geolocation and QR code-based marking.
✅ Authentication
- Email/password registration and login
- Role-based access (Student/Lecturer)
- Firebase Authentication
✅ Lecturer Features
- Create attendance sessions
- Set attendance radius (10-1000m)
- Set session duration
- Real-time geolocation support
- QR code generation and display
- Live attendance list with real-time updates
- Session countdown timer
✅ Student Features
- Automatic active session detection
- Geolocation-based attendance (Haversine distance)
- QR code scanning
- Real-time attendance confirmation
- Duplicate prevention
✅ Technical
- Client-side only (Firebase backend)
- No Node.js required
- HTTPS compatible
- Responsive design
- Modular JavaScript
- Real-time Firestore updates
GeoAttend/
├── index.html # Login/Signup page
├── lecturer.html # Lecturer dashboard
├── student.html # Student dashboard
├── css/
│ └── style.css # All styling
├── js/
│ ├── firebase.js # Firebase initialization
│ ├── auth.js # Authentication functions
│ ├── lecturer.js # Lecturer logic
│ ├── student.js # Student logic
│ └── qr.js # QR code generation
├── FIREBASE_CONFIG_TEMPLATE.md # Setup instructions
└── FIRESTORE_RULES.txt # Security rules
- Go to Firebase Console
- Create a new project (name it "GeoAttend" or similar)
- Wait for project creation to complete
- Navigate to Authentication (left sidebar)
- Click Sign-in method
- Enable Email/Password
- Save
- Navigate to Firestore Database (left sidebar)
- Click Create database
- Choose Start in production mode
- Select a region (closest to you)
- Click Enable
- Go to Project Settings (gear icon, top-left)
- Under General tab, find Your apps section
- If no app exists, click Add app → Web
- Register your app
- Copy the Firebase config object
- In Firestore Database, click Rules tab
- Replace all content with the rules from
FIRESTORE_RULES.txt - Click Publish
- Open
js/firebase.js - Replace the placeholder values:
const firebaseConfig = { apiKey: "YOUR_API_KEY_HERE", authDomain: "YOUR_PROJECT_ID.firebaseapp.com", projectId: "YOUR_PROJECT_ID_HERE", storageBucket: "YOUR_PROJECT_ID.appspot.com", messagingSenderId: "YOUR_MESSAGING_SENDER_ID_HERE", appId: "YOUR_APP_ID_HERE" };
npm install -g firebase-tools
firebase login
firebase init
firebase emulators:startcd c:\Users\hp\Desktop\GeoAttend
python -m http.server 8000Then visit http://localhost:8000
Note: Geolocation requires HTTPS, so testing on localhost is fine, but on production you MUST use HTTPS.
- Install "Live Server" extension
- Right-click
index.html - Select "Open with Live Server"
npm install -g firebase-tools
firebase login
firebase init hosting
# Select your project
# Set public directory to current directory
firebase deploy- Push this repository to GitHub
- Go to Vercel
- Import your GitHub repository
- Deploy (automatically serves as static)
- Login with lecturer email/password
- Set Parameters:
- Attendance Radius: Distance students must be within (meters)
- Session Duration: How long the session runs (minutes)
- Click Start Session:
- System requests your location
- If granted: Creates geolocation + QR session
- If denied: Creates QR-only session
- Share QR Code with students
- Monitor real-time attendance list
- End Session when done
- Login with student email/password
- Auto-detection: Active session automatically shows on dashboard
- If Geolocation Session:
- System requests permission
- Device location checked every 15 seconds
- Marked present when within radius
- If QR-Only Session:
- Click "Scan QR Code"
- Scan lecturer's QR code
- Or manually enter session ID
- Confirmation: See "Attendance Recorded" message
Calculates distance between two geographic coordinates:
Distance (meters) = 2 * R * arcsin(√(sin²(Δφ/2) + cos(φ1) * cos(φ2) * sin²(Δλ/2)))
Where:
- R = Earth's radius (6,371,000 meters)
- φ = latitude
- λ = longitude
Attendance documents use composite ID:
docId = ${sessionId}_${studentId}
This ensures one attendance record per student per session.
{
role: "student" | "lecturer",
name: string,
level: string (students only),
email: string,
createdAt: timestamp
}
{
lecturerId: uid,
lecturerName: string,
startTime: timestamp,
endTime: timestamp,
latitude: number | null,
longitude: number | null,
radius: number,
active: boolean,
geoEnabled: boolean,
qrOnly: boolean,
qrValue: string (= sessionId)
}
{
sessionId: string,
studentId: uid,
name: string,
level: string,
timestamp: timestamp,
method: "Geo" | "QR"
}
✅ Authentication
- Firebase Auth handles password hashing
- Email verification optional (can be added)
✅ Database Rules
- Users read only own profile
- Students write only own attendance
- Lecturers create only own sessions
- Attendance records immutable
✅ Privacy
- Student coordinates NOT stored
- Only lecturer coordinates stored (once per session)
- Attendance records show only name, level, method, time
✅ HTTPS Required
- Geolocation API requires secure context
- Deploy with HTTPS only
Problem: "Waiting for location..." never resolves
- Cause: User denied permission or browser blocking
- Solution:
- Check browser location permissions
- Use HTTPS connection
- Try QR-only mode as alternative
Problem: Empty container where QR should be
- Cause: qrcode.js library not loaded
- Solution:
- Check internet connection (CDN access)
- Check browser console for errors
- Verify session ID is valid
Problem: Students marked present but not showing
- Cause: Real-time listener not subscribed
- Solution:
- Check Firestore rules applied correctly
- Verify student wrote to correct session ID
- Check browser console for errors
Problem: Lecturer created session but student sees nothing
- Cause:
- Query timeout or network issue
- Session not marked as active
- Solution:
- Refresh page
- Verify lecturer session shows "Active"
- Check Firestore database for session document
| Browser | Geolocation | QR Camera | Overall | Notes |
|---|---|---|---|---|
| Chrome | ✅ Full | ✅ Full | ✅ Full | Recommended, works perfectly |
| Firefox | ✅ Full | ✅ Full | ✅ Full | Works perfectly |
| Safari | ✅ Full | ✅ Full | ✅ Full | Works perfectly |
| Edge | ✅ Full | ✅ Full | ✅ Full | Works perfectly |
| IE 11 | ❌ None | ❌ None | ❌ None | Not supported |
Requirements: HTTPS for geolocation and camera access (localhost allowed for dev)
| Browser | Geolocation | QR Camera | Overall | Notes |
|---|---|---|---|---|
| Chrome | ✅ Full | ✅ Full | ✅ Full | Recommended |
| Firefox | ✅ Full | ✅ Full | ✅ Full | Works great |
| Samsung Internet | ✅ Full | ✅ Full | ✅ Full | Works great |
| Edge | ✅ Full | ✅ Full | ✅ Full | Works great |
| Opera | ✅ Full | ✅ Full | ✅ Full | Works great |
| Chrome Lite | ✅ Full | Geolocation may not work |
Requirements: HTTPS, Android 5.0+ recommended
| Browser | Geolocation | QR Camera | Overall | Notes |
|---|---|---|---|---|
| Safari | ✅ Full | ✅ Full | ✅ Recommended | Full native API access |
| Chrome | ❌ Restricted | ❌ Not Recommended | Uses WebKit (Apple requirement) with restricted APIs | |
| Firefox | ❌ Restricted | ❌ Not Recommended | Uses WebKit (Apple requirement) with restricted APIs | |
| Edge | ❌ Restricted | ❌ Not Recommended | Uses WebKit (Apple requirement) with restricted APIs | |
| Opera | ❌ Restricted | ❌ Not Recommended | Uses WebKit (Apple requirement) with restricted APIs |
Key Points:
- Safari on iOS: ✅ Full support - can use geolocation and camera normally
- All other browsers on iOS: ❌ Have restricted geolocation (returns cached/fake data due to Apple's WebKit requirement)
- Fallback: Non-Safari iOS browsers automatically detect restriction and switch to QR code instead
- Manual Entry: If camera also fails, users can manually enter session ID (always available as fallback)
Requirements: HTTPS, iOS 12+ recommended
The system automatically handles all scenarios:
Geolocation-based session?
├─ YES → Try geolocation
│ ├─ Success → Use geolocation
│ ├─ Permission denied → Switch to QR
│ ├─ Location unavailable → Retry or switch to QR
│ └─ Non-Safari iOS → Show warning, switch to QR
│
└─ NO → Use QR code directly
QR Camera?
├─ Success → Scan QR code
├─ Permission denied → Show manual entry form
├─ Camera unavailable → Show manual entry form
└─ Any error → Manual entry form (always available)
Manual Entry?
└─ Always works → User enters session ID manually
- Reduce Polling Interval: Change 15s to 30s in
student.jsfor less battery drain - Optimize QR Size: Adjust in
qr.jsfor faster scanning - Database Indexes: Consider adding composite indexes for common queries
- Cache Authentication: Tokens cached automatically by Firebase SDK
- iOS Recommendation: Use Safari for best geolocation experience
- Real-time notifications for students
- SMS alerts
- Face recognition
- Multiple attendance methods per session
- Offline support
- Analytics dashboard
- Export attendance to CSV/PDF
MIT
For issues or questions:
- Check the troubleshooting section
- Review browser console for errors
- Verify Firebase configuration
- Check Firestore rules are applied
setupAuthListener(callback)- Listen to auth state changesgetCurrentUser()- Get current user async
registerUser(email, password, name, role, level)- Create accountloginUser(email, password)- Sign inlogoutUser()- Sign outgetUserProfile(uid)- Fetch user dataupdateUserProfile(uid, data)- Update user data
initLecturerDashboard()- Initialize lecturer page
initStudentDashboard()- Initialize student pagesetupQRScanning()- Setup QR scanning button
generateQRCode(text, elementId)- Generate QR codedisplayQRCodeWithText(sessionId, elementId, text)- Display with labeldownloadQRCode(filename)- Download as PNG
Status: ✅ Production Ready Last Updated: January 2026 Version: 1.0.0 README generated by Artificial Intelligence, after prompt from User.