363 lines
9.7 KiB
Dart
363 lines
9.7 KiB
Dart
import 'package:firebase_analytics/firebase_analytics.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// Firebase Analytics service for tracking user events across the app.
|
|
///
|
|
/// Usage:
|
|
/// ```dart
|
|
/// // Log add to cart event
|
|
/// AnalyticsService.logAddToCart(
|
|
/// productId: 'SKU123',
|
|
/// productName: 'Gạch men 60x60',
|
|
/// price: 150000,
|
|
/// quantity: 2,
|
|
/// );
|
|
/// ```
|
|
class AnalyticsService {
|
|
AnalyticsService._();
|
|
|
|
static final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;
|
|
|
|
/// Get the analytics instance for NavigatorObserver
|
|
static FirebaseAnalytics get instance => _analytics;
|
|
|
|
/// Get the observer for automatic screen tracking in GoRouter
|
|
static FirebaseAnalyticsObserver get observer => FirebaseAnalyticsObserver(
|
|
analytics: _analytics,
|
|
nameExtractor: (settings) {
|
|
// GoRouter uses the path as the route name
|
|
final name = settings.name;
|
|
if (name != null && name.isNotEmpty && name != '/') {
|
|
return name;
|
|
}
|
|
return settings.name ?? '/';
|
|
},
|
|
routeFilter: (route) => route is PageRoute,
|
|
);
|
|
|
|
/// Log screen view manually
|
|
static Future<void> logScreenView({
|
|
required String screenName,
|
|
String? screenClass,
|
|
}) async {
|
|
try {
|
|
await _analytics.logScreenView(
|
|
screenName: screenName,
|
|
screenClass: screenClass,
|
|
);
|
|
debugPrint('📊 Analytics: screen_view - $screenName');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// E-commerce Events
|
|
// ============================================================================
|
|
|
|
/// Log view item event - when user views product detail
|
|
static Future<void> logViewItem({
|
|
required String productId,
|
|
required String productName,
|
|
required double price,
|
|
String? brand,
|
|
String? category,
|
|
}) async {
|
|
try {
|
|
await _analytics.logViewItem(
|
|
currency: 'VND',
|
|
value: price,
|
|
items: [
|
|
AnalyticsEventItem(
|
|
itemId: productId,
|
|
itemName: productName,
|
|
price: price,
|
|
itemBrand: brand,
|
|
itemCategory: category,
|
|
),
|
|
],
|
|
);
|
|
debugPrint('📊 Analytics: view_item - $productName');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log add to cart event
|
|
static Future<void> logAddToCart({
|
|
required String productId,
|
|
required String productName,
|
|
required double price,
|
|
required int quantity,
|
|
String? brand,
|
|
}) async {
|
|
try {
|
|
await _analytics.logAddToCart(
|
|
currency: 'VND',
|
|
value: price * quantity,
|
|
items: [
|
|
AnalyticsEventItem(
|
|
itemId: productId,
|
|
itemName: productName,
|
|
price: price,
|
|
quantity: quantity,
|
|
itemBrand: brand,
|
|
),
|
|
],
|
|
);
|
|
debugPrint('📊 Analytics: add_to_cart - $productName x$quantity');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log remove from cart event
|
|
static Future<void> logRemoveFromCart({
|
|
required String productId,
|
|
required String productName,
|
|
required double price,
|
|
required int quantity,
|
|
}) async {
|
|
try {
|
|
await _analytics.logRemoveFromCart(
|
|
currency: 'VND',
|
|
value: price * quantity,
|
|
items: [
|
|
AnalyticsEventItem(
|
|
itemId: productId,
|
|
itemName: productName,
|
|
price: price,
|
|
quantity: quantity,
|
|
),
|
|
],
|
|
);
|
|
debugPrint('📊 Analytics: remove_from_cart - $productName');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log view cart event
|
|
static Future<void> logViewCart({
|
|
required double cartValue,
|
|
required List<AnalyticsEventItem> items,
|
|
}) async {
|
|
try {
|
|
await _analytics.logViewCart(
|
|
currency: 'VND',
|
|
value: cartValue,
|
|
items: items,
|
|
);
|
|
debugPrint('📊 Analytics: view_cart - ${items.length} items');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log begin checkout event
|
|
static Future<void> logBeginCheckout({
|
|
required double value,
|
|
required List<AnalyticsEventItem> items,
|
|
String? coupon,
|
|
}) async {
|
|
try {
|
|
await _analytics.logBeginCheckout(
|
|
currency: 'VND',
|
|
value: value,
|
|
items: items,
|
|
coupon: coupon,
|
|
);
|
|
debugPrint('📊 Analytics: begin_checkout - $value VND');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log purchase event - when order is completed
|
|
static Future<void> logPurchase({
|
|
required String orderId,
|
|
required double value,
|
|
required List<AnalyticsEventItem> items,
|
|
double? shipping,
|
|
double? tax,
|
|
String? coupon,
|
|
}) async {
|
|
try {
|
|
await _analytics.logPurchase(
|
|
currency: 'VND',
|
|
transactionId: orderId,
|
|
value: value,
|
|
items: items,
|
|
shipping: shipping,
|
|
tax: tax,
|
|
coupon: coupon,
|
|
);
|
|
debugPrint('📊 Analytics: purchase - Order $orderId');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Search & Discovery Events
|
|
// ============================================================================
|
|
|
|
/// Log search event
|
|
static Future<void> logSearch({
|
|
required String searchTerm,
|
|
}) async {
|
|
try {
|
|
await _analytics.logSearch(searchTerm: searchTerm);
|
|
debugPrint('📊 Analytics: search - $searchTerm');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log select item event - when user taps on a product in list
|
|
static Future<void> logSelectItem({
|
|
required String productId,
|
|
required String productName,
|
|
String? listName,
|
|
}) async {
|
|
try {
|
|
await _analytics.logSelectItem(
|
|
itemListName: listName,
|
|
items: [
|
|
AnalyticsEventItem(
|
|
itemId: productId,
|
|
itemName: productName,
|
|
),
|
|
],
|
|
);
|
|
debugPrint('📊 Analytics: select_item - $productName');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Loyalty & Rewards Events
|
|
// ============================================================================
|
|
|
|
/// Log earn points event
|
|
static Future<void> logEarnPoints({
|
|
required int points,
|
|
required String source,
|
|
}) async {
|
|
try {
|
|
await _analytics.logEarnVirtualCurrency(
|
|
virtualCurrencyName: 'loyalty_points',
|
|
value: points.toDouble(),
|
|
);
|
|
debugPrint('📊 Analytics: earn_points - $points from $source');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log spend points event - when user redeems points
|
|
static Future<void> logSpendPoints({
|
|
required int points,
|
|
required String itemName,
|
|
}) async {
|
|
try {
|
|
await _analytics.logSpendVirtualCurrency(
|
|
virtualCurrencyName: 'loyalty_points',
|
|
value: points.toDouble(),
|
|
itemName: itemName,
|
|
);
|
|
debugPrint('📊 Analytics: spend_points - $points for $itemName');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// User Events
|
|
// ============================================================================
|
|
|
|
/// Log login event
|
|
static Future<void> logLogin({
|
|
String? method,
|
|
}) async {
|
|
try {
|
|
await _analytics.logLogin(loginMethod: method ?? 'phone');
|
|
debugPrint('📊 Analytics: login - $method');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log sign up event
|
|
static Future<void> logSignUp({
|
|
String? method,
|
|
}) async {
|
|
try {
|
|
await _analytics.logSignUp(signUpMethod: method ?? 'phone');
|
|
debugPrint('📊 Analytics: sign_up - $method');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Log share event
|
|
static Future<void> logShare({
|
|
required String contentType,
|
|
required String itemId,
|
|
String? method,
|
|
}) async {
|
|
try {
|
|
await _analytics.logShare(
|
|
contentType: contentType,
|
|
itemId: itemId,
|
|
method: method ?? 'unknown',
|
|
);
|
|
debugPrint('📊 Analytics: share - $contentType $itemId');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Custom Events
|
|
// ============================================================================
|
|
|
|
/// Log custom event
|
|
static Future<void> logEvent({
|
|
required String name,
|
|
Map<String, Object>? parameters,
|
|
}) async {
|
|
try {
|
|
await _analytics.logEvent(name: name, parameters: parameters);
|
|
debugPrint('📊 Analytics: $name');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Set user ID for analytics
|
|
static Future<void> setUserId(String? userId) async {
|
|
try {
|
|
await _analytics.setUserId(id: userId);
|
|
debugPrint('📊 Analytics: setUserId - $userId');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
|
|
/// Set user property
|
|
static Future<void> setUserProperty({
|
|
required String name,
|
|
required String? value,
|
|
}) async {
|
|
try {
|
|
await _analytics.setUserProperty(name: name, value: value);
|
|
debugPrint('📊 Analytics: setUserProperty - $name: $value');
|
|
} catch (e) {
|
|
debugPrint('📊 Analytics error: $e');
|
|
}
|
|
}
|
|
}
|