firstusers
v1.2.0
Published
Usage tracking SDK for React Native/Expo apps. Tracks authenticated user sessions with 30s heartbeat to First Users platform.
Downloads
533
Maintainers
Readme
firstusers
Session tracking SDK for React Native/Expo apps. Tracks authenticated user sessions with automatic 30-second heartbeat updates.
Features
✅ Post-Login Tracking - Only tracks authenticated user sessions (excludes login screen time)
✅ Automatic Heartbeat - Updates session duration every 30 seconds
✅ Survives App Kill - Last heartbeat data already saved (max 30s loss)
✅ Zero Configuration - Expo Config Plugin auto-configures your project
✅ Privacy-Focused - No sensitive data collection
✅ Lightweight - Minimal battery and performance impact
Installation
npm install firstusersOr with yarn:
yarn add firstusersConfiguration
Step 1: Add Plugin to app.json
{
"expo": {
"plugins": [
[
"firstusers",
{
"apiUrl": "https://your-api.workers.dev"
}
]
]
}
}Plugin Options:
| Option | Type | Required | Default |
|--------|------|----------|---------|
| apiUrl | string | No | https://cotester-api.01hunterwl.workers.dev |
Step 2: Rebuild Your App
The Config Plugin needs a native rebuild to apply changes:
# Development build
npx expo run:android
# Or prebuild for custom builds
npx expo prebuild --clean⚠️ Important: You must rebuild the app after installing this package. Expo Go does not support custom native modules.
Usage
Basic Setup
import futracker from 'firstusers';
import { supabase } from './lib/supabase';
// Configure once at app startup
futracker.configure('https://your-api.workers.dev');
futracker.setPackageName('com.yourcompany.app');
// Start tracking after successful login
supabase.auth.onAuthStateChange((event, session) => {
if (event === 'SIGNED_IN' && session) {
futracker.startTracking();
}
});Alternative: Convenience Function
import { startTracking } from 'firstusers';
// One-line start with package name
if (loginSuccess) {
startTracking('com.yourcompany.app');
}Optional: Manual Stop (usually not needed)
import { stopTracking } from 'firstusers';
// Optional: Call on logout
function handleLogout() {
stopTracking(); // Not required - heartbeat already saved data
// ... rest of logout logic
}API Reference
futracker.configure(apiUrl: string)
Configure the API endpoint. Call once at app startup.
Parameters:
apiUrl(string) - Your First Users API endpoint
Example:
futracker.configure('https://your-api.workers.dev');futracker.setPackageName(packageName: string)
Set your app's package name (same as applicationId in build.gradle).
Parameters:
packageName(string) - Your app's package name
Example:
futracker.setPackageName('com.yourcompany.app');futracker.startTracking(packageName?: string)
Start tracking user session. Call after successful login.
Parameters:
packageName(string, optional) - Override package name for this call
Example:
// Use pre-configured package name
futracker.startTracking();
// Or pass directly
futracker.startTracking('com.yourcompany.app');futracker.stopTracking()
Stop tracking session. Optional - heartbeat auto-saves data every 30s.
Example:
futracker.stopTracking();futracker.setDebug(enabled: boolean)
Enable or disable debug logging. Debug mode is enabled by default.
Parameters:
enabled(boolean) - Whether to enable debug logs
Example:
// Disable debug logs in production
futracker.setDebug(false);futracker.isActive()
Check if tracking is currently active.
Returns: boolean indicating if tracking is active
Example:
if (futracker.isActive()) {
console.log('Tracking is running');
}How It Works
- Initial Record: When
startTracking()is called, creates one record infu_trackingtable withsession_duration = 0 - Heartbeat Updates: Every 30 seconds, UPDATE the same record's
session_durationto current elapsed time - App Kill Safety: If app is killed, last heartbeat data is already saved (accurate within ~30 seconds)
- No Data Loss: No need to call
stopTracking()- heartbeat already persisted the duration
Database Schema
The tracker sends data to the fu_tracking table:
CREATE TABLE fu_tracking (
id INTEGER PRIMARY KEY AUTOINCREMENT,
fu_id TEXT NOT NULL, -- Guest ID (gu-XXXXX) or User ID (fu-XXXXX)
app_package TEXT NOT NULL, -- Your app's package name
timestamp TEXT NOT NULL, -- ISO 8601 UTC timestamp
action TEXT NOT NULL, -- 'session_start'
device_brand TEXT, -- Device manufacturer
device_api_level TEXT, -- Android version
user_agent TEXT, -- Platform info
session_id TEXT NOT NULL, -- Unique session identifier
session_duration INTEGER NOT NULL -- Seconds since session start
);Data Collected
Session Data:
- Session start time (UTC timestamp)
- Session duration (seconds)
- Session ID (unique per app open)
Device Info:
- Device manufacturer (e.g., "Google", "Samsung")
- Android API level (e.g., "Android 33")
- Platform (e.g., "Android/13")
No Personal Data:
- ❌ No user location
- ❌ No contact information
- ❌ No sensitive permissions
Troubleshooting
Module not found error
Error: The package 'firstusers' doesn't seem to be linked
Solution: You must rebuild the native app:
npx expo run:androidTracking not starting
Check:
- Did you call
setPackageName()beforestartTracking()? - Is the package name correct? (Check
android/app/build.gradle→applicationId) - Did you rebuild after installing the package?
Debug:
// Enable console logs
futracker.configure('https://your-api.workers.dev');
futracker.setPackageName('com.yourcompany.app');
futracker.startTracking();
// Check console for "[FirstUsers]" logsBuild errors
Error: Plugin [id: 'expo-module-gradle-plugin'] was not found
Solution: Clean and rebuild:
cd android
./gradlew clean
cd ..
npx expo prebuild --clean
npx expo run:androidRequirements
- React Native: 0.70+
- Expo: 50+
- Android: API 24+ (Android 7.0)
- Kotlin: 1.8+
Example Integration
Complete example with Supabase authentication:
// App.tsx
import React, { useEffect } from 'react';
import futracker from 'firstusers';
import { supabase } from './lib/supabase';
export default function App() {
useEffect(() => {
// Configure tracker once
futracker.configure('https://cotester-api.01hunterwl.workers.dev');
futracker.setPackageName('net.woodlogos.app.firstusers');
// Listen for auth changes
const { data: authListener } = supabase.auth.onAuthStateChange(
async (event, session) => {
if (event === 'SIGNED_IN' && session) {
// Start tracking after successful login
futracker.startTracking();
console.log('✅ Tracking started for authenticated user');
}
}
);
return () => {
authListener?.subscription.unsubscribe();
};
}, []);
return (
// Your app components
);
}Privacy & Compliance
GDPR Compliant: Only tracks usage duration and basic device info (no personal data)
Disclose in Privacy Policy:
This app collects anonymous usage data for beta testing:
- Session duration (start/end time)
- Device model and Android version
- App package name
No personal information is collected.License
MIT
Support
- Issues: GitHub Issues
- Documentation: GitHub Wiki
- Email: [email protected]
Made with ❤️ by First Users Team
