MobilApp/lib/services/firebase_logger.dart

192 lines
6.1 KiB
Dart

// Firebase alapú log service — Crashlytics + Analytics
//
// Crashlytics: breadcrumb log, hiba rögzítés, egyedi attribútumok
// Analytics: egyedi esemény tracking (warning-ok, hibák, fontos események)
//
// Éles appban is működik — kiegészíti az AppLogger-t (ami csak debug módban fut)
//
// Használat:
// FirebaseLogger.i('startRecording', 'Track indítva: $name');
// FirebaseLogger.w('_onPosition', 'Ugrás kiszűrve: ${dist}m');
// FirebaseLogger.e('positionStream', 'GPS hiba', error: e, stack: s);
// FirebaseLogger.event('track_completed', {'distance_m': 3200, 'points': 142});
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
class FirebaseLogger extends GetxService {
static FirebaseLogger get to => Get.find();
// ── Belső referenciák ─────────────────────────────────────────────
late final FirebaseCrashlytics _crashlytics;
late final FirebaseAnalytics _analytics;
bool _isReady = false;
// ── Lifecycle ─────────────────────────────────────────────────────
@override
Future<void> onReady() async {
super.onReady();
try {
_crashlytics = FirebaseCrashlytics.instance;
_analytics = FirebaseAnalytics.instance;
// Crashlytics engedélyezése — release-ben mindig, debug-ban opcionális
//await _crashlytics.setCrashlyticsCollectionEnabled(!kDebugMode);
await _crashlytics.setCrashlyticsCollectionEnabled(true);
// Eszközazonosító beállítása ha már elérhető
_setDeviceInfo();
_isReady = true;
_crashlytics.log('FirebaseLogger inicializálva');
} catch (e) {
debugPrint('FirebaseLogger init hiba: $e');
}
}
// ── Publikus API — ugyanolyan mint AppLogger ──────────────────────
/// Info szintű log — Crashlytics breadcrumb
static void i(String tag, String message) {
_breadcrumb('I', tag, message);
}
/// Figyelmeztetés — breadcrumb + Analytics esemény
static void w(String tag, String message, {Object? error}) {
_breadcrumb('W', tag, message);
_logWarningEvent(tag, message, error: error);
}
/// Hiba — Crashlytics recordError + Analytics esemény
static void e(
String tag,
String message, {
Object? error,
StackTrace? stack,
bool fatal = false,
}) {
_breadcrumb('E', tag, message);
if (error != null) {
try {
FirebaseLogger.to._crashlytics.recordError(
error,
stack,
reason: '[$tag] $message',
fatal: fatal,
printDetails: kDebugMode,
information: ['tag: $tag', 'message: $message'],
);
} catch (_) {}
}
_logErrorEvent(tag, message, error: error);
}
/// Szeparátor — jól látható elválasztó a Crashlytics logban
static void separator(String label) {
_breadcrumb('', '─────', '─── $label ───────────────────────');
}
/// Egyedi Analytics esemény — tetszőleges adatokkal
static void event(
String name, [
Map<String, Object>? parameters,
]) {
try {
FirebaseLogger.to._analytics.logEvent(
name: _sanitizeEventName(name),
parameters: parameters,
);
} catch (_) {}
}
/// Egyedi Crashlytics attribútum beállítása
static void setKey(String key, dynamic value) {
try {
FirebaseLogger.to._crashlytics.setCustomKey(key, value);
} catch (_) {}
}
// ── Eszközinfo beállítása ─────────────────────────────────────────
void _setDeviceInfo() {
try {
// DeviceIdentityService ha már elérhető
if (Get.isRegistered<dynamic>()) {
final deviceService = Get.find(tag: 'DeviceIdentityService');
_crashlytics.setUserIdentifier(deviceService.deviceId ?? '');
}
} catch (_) {
// DeviceIdentityService még nem regisztrált — nem baj
}
}
/// Crashlytics azonosító frissítése ha a DeviceIdentityService betöltött
static void setDeviceIdentifier(String deviceId, String label) {
try {
FirebaseLogger.to._crashlytics.setUserIdentifier(deviceId);
FirebaseLogger.to._crashlytics.setCustomKey('device_label', label);
} catch (_) {}
}
// ── Belső segédek ─────────────────────────────────────────────────
static void _breadcrumb(String level, String tag, String message) {
try {
final line = '$level [$tag] $message';
FirebaseLogger.to._crashlytics.log(line);
} catch (_) {}
}
static void _logWarningEvent(
String tag,
String message, {
Object? error,
}) {
try {
FirebaseLogger.to._analytics.logEvent(
name: 'app_warning',
parameters: {
'tag': _trim(tag, 40),
'message': _trim(message, 100),
if (error != null) 'error': _trim(error.toString(), 100),
},
);
} catch (_) {}
}
static void _logErrorEvent(
String tag,
String message, {
Object? error,
}) {
try {
FirebaseLogger.to._analytics.logEvent(
name: 'app_error',
parameters: {
'tag': _trim(tag, 40),
'message': _trim(message, 100),
if (error != null) 'error': _trim(error.toString(), 100),
},
);
} catch (_) {}
}
/// Analytics eseménynevek csak betűt, számot és _ -t tartalmazhatnak
static String _sanitizeEventName(String name) =>
name.replaceAll(RegExp(r'[^a-zA-Z0-9_]'), '_').substring(
0,
name.length.clamp(0, 40),
);
/// Analytics paraméter érték max 100 karakter
static String _trim(String s, int max) =>
s.length > max ? s.substring(0, max) : s;
}