Skip to content

Commit 982aa65

Browse files
committed
app changes for getting stats regarding installations and the debug logs if any issues occures in device
1 parent 9a53df0 commit 982aa65

5 files changed

Lines changed: 122 additions & 0 deletions

File tree

AndroidApp/App.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
Animated,
1212
Easing,
1313
LogBox,
14+
Alert,
15+
Share,
1416
} from 'react-native';
1517

1618
LogBox.ignoreLogs([
@@ -22,6 +24,38 @@ import { AppDetailsPopup } from './src/components/AppDetailsPopup';
2224
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
2325
import messaging from '@react-native-firebase/messaging';
2426
import { PermissionsAndroid, Platform } from 'react-native';
27+
import { setJSExceptionHandler, setNativeExceptionHandler } from 'react-native-exception-handler';
28+
import { trackInstall, logFatalCrash } from './src/config/telemetry';
29+
30+
// Handle JS Crashes
31+
setJSExceptionHandler((error, isFatal) => {
32+
if (isFatal) {
33+
const errorString = `${error.name}: ${error.message}\n${error.stack}`;
34+
logFatalCrash(errorString, isFatal);
35+
36+
Alert.alert(
37+
'Unexpected Error',
38+
'The App Hub encountered a critical error. Your crash log has been securely tracked, but you can also share it manually with the developer.',
39+
[
40+
{
41+
text: 'Share Log',
42+
onPress: () => {
43+
Share.share({ message: `Fatal App Crash Log:\n\n${errorString}` });
44+
}
45+
},
46+
{
47+
text: 'Close',
48+
}
49+
]
50+
);
51+
}
52+
}, true);
53+
54+
// Handle Native Crashes
55+
setNativeExceptionHandler((errorString) => {
56+
logFatalCrash(errorString, true);
57+
});
58+
2559
const { width, height } = Dimensions.get('window');
2660

2761
// --- Skeleton Card Component ---
@@ -105,6 +139,7 @@ function App(): React.JSX.Element {
105139
};
106140

107141
useEffect(() => {
142+
trackInstall();
108143
loadApps();
109144

110145
const requestPermissions = async () => {

AndroidApp/package-lock.json

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

AndroidApp/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"@supabase/supabase-js": "^2.98.0",
1818
"react": "19.2.3",
1919
"react-native": "0.84.0",
20+
"react-native-device-info": "^15.0.2",
21+
"react-native-exception-handler": "^2.10.10",
2022
"react-native-file-viewer": "^2.1.5",
2123
"react-native-fs": "^2.20.0",
2224
"react-native-intent-launcher": "^0.2.1",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
diff --git a/node_modules/react-native-exception-handler/android/build.gradle b/node_modules/react-native-exception-handler/android/build.gradle
2+
index c1dca20..21596d5 100644
3+
--- a/node_modules/react-native-exception-handler/android/build.gradle
4+
+++ b/node_modules/react-native-exception-handler/android/build.gradle
5+
@@ -1,7 +1,7 @@
6+
7+
buildscript {
8+
repositories {
9+
- jcenter()
10+
+ mavenCentral()
11+
}
12+
13+
dependencies {

AndroidApp/src/config/telemetry.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import DeviceInfo from 'react-native-device-info';
2+
import { supabase } from './supabase';
3+
4+
export const trackInstall = async () => {
5+
try {
6+
const uniqueId = await DeviceInfo.getUniqueId();
7+
const brand = await DeviceInfo.getBrand();
8+
const model = await DeviceInfo.getModel();
9+
const systemVersion = await DeviceInfo.getSystemVersion();
10+
11+
// Perform an UPSERT to update 'last_opened' without duplicating the device entry for 'installed_at'
12+
const { error } = await supabase.from('installs').upsert(
13+
{
14+
device_id: uniqueId,
15+
brand,
16+
model,
17+
system_version: systemVersion,
18+
last_opened: new Date().toISOString()
19+
},
20+
{ onConflict: 'device_id' }
21+
);
22+
23+
if (error) {
24+
console.warn('Telemetry: Fail to track install', error);
25+
} else {
26+
console.log('Telemetry: App Launch tracked safely.');
27+
}
28+
} catch (e) {
29+
console.error('Telemetry Error:', e);
30+
}
31+
};
32+
33+
export const logFatalCrash = async (errorString: string, isFatal: boolean) => {
34+
try {
35+
const uniqueId = await DeviceInfo.getUniqueId();
36+
const systemName = await DeviceInfo.getSystemName();
37+
38+
const { error } = await supabase.from('error_logs').insert({
39+
device_id: uniqueId,
40+
error_message: isFatal ? 'Fatal Crash' : 'Caught Exception',
41+
stack_trace: errorString,
42+
platform: systemName
43+
});
44+
45+
if (error) {
46+
console.warn('Telemetry: Failed to upload crash log', error);
47+
}
48+
} catch (e) {
49+
console.error('Telemetry Crash Logger Error:', e);
50+
}
51+
};

0 commit comments

Comments
 (0)