191 lines
6.0 KiB
Dart
191 lines
6.0 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);
|
||
|
|
|
||
|
|
// 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;
|
||
|
|
}
|