flutter_estatisticas 0.2.2 copy "flutter_estatisticas: ^0.2.2" to clipboard
flutter_estatisticas: ^0.2.2 copied to clipboard

A Flutter package for integrating Umami Analytics into your apps. Track navigation and custom events easily, providing privacy-friendly analytics for your users.

Flutter Umami Analytics Integration #

pub package License: MIT

A comprehensive Flutter package that integrates Umami Analytics into your Flutter app. This package provides both tracking capabilities (pageviews and custom events) and full REST API management for websites, users, teams, and analytics data.

🚀 Features #

  • 📊 Event Tracking: Automatic navigation tracking and custom events
  • 🔐 Authentication: Login and token management for self-hosted Umami
  • 👥 User Management: Create, update, delete users and manage permissions
  • 🏢 Team Management: Team creation, user roles, and collaboration
  • 🌐 Website Management: Website CRUD operations and analytics
  • 📈 Analytics Data: Retrieve pageviews, events, sessions, and metrics
  • ☁️ Umami Cloud Support: Works with both self-hosted and Umami Cloud
  • 🔒 No-Auth Tracking: Send events without authentication using /api/send

📦 Installation #

Add to your pubspec.yaml:

dependencies:
  flutter_estatisticas: ^0.2.2

Then run:

flutter pub get

🎯 Quick Start #

1. Basic Event Tracking (No Authentication Required) #

Perfect for simple analytics tracking without managing authentication.

import 'package:flutter_estatisticas/umami_service.dart';
import 'package:flutter_estatisticas/umami_navigation_observer.dart';

// Instantiate the service
final umamiService = UmamiService(
  endpoint: 'https://cloud.umami.is',     // Umami Cloud or your endpoint
  website: 'your-website-id',            // Website ID from Umami dashboard
  hostname: 'your-app.com',              // Your app's identifier
);

// Add to MaterialApp for automatic navigation tracking
MaterialApp(
  navigatorObservers: [
    UmamiNavigationObserver(umamiService),
  ],
  // ... rest of your app
)

// Send custom events
umamiService.enviarClique(
  context,
  'Home Page',
  'subscribe_button',
);

umamiService.enviarEvento(
  context,
  title: 'Settings',
  name: 'theme_changed',
  data: {'theme': 'dark'},
);

2. Advanced Analytics with REST API #

For complete control over your Umami instance, including user and website management.

import 'package:flutter_estatisticas/services/umami_auth_service.dart';
import 'package:flutter_estatisticas/services/umami_website_service.dart';

final authService = UmamiAuthService(
  endpoint: 'https://your-umami-instance.com'
);

final websiteService = UmamiWebsiteService(
  endpoint: 'https://your-umami-instance.com'
);

// Login (self-hosted only)
final loginResponse = await authService.login(
  username: 'admin',
  password: 'password',
);

final token = loginResponse?['token'];

// Get website analytics
final stats = await websiteService.getWebsiteStats(
  token: token!,
  websiteId: 'website-id',
  startAt: DateTime.now().subtract(Duration(days: 7)).millisecondsSinceEpoch,
  endAt: DateTime.now().millisecondsSinceEpoch,
);

📋 Available Services #

🔐 Authentication Service (UmamiAuthService) #

final authService = UmamiAuthService(endpoint: 'https://your-endpoint.com');

// Login
final response = await authService.login(
  username: 'admin',
  password: 'password',
);

// Verify token
final isValid = await authService.isTokenValid(token);

👥 User Management (UmamiUserService) #

final userService = UmamiUserService(endpoint: 'https://your-endpoint.com');

// Create user
final user = await userService.createUser(
  token: token,
  username: 'newuser',
  password: 'password',
  role: 'user', // 'admin', 'user', or 'view-only'
);

// Get all users (admin only)
final users = await userService.getAllUsers(token: token);

// Get user websites
final websites = await userService.getUserWebsites(
  token: token,
  userId: 'user-id',
);

🏢 Team Management (UmamiTeamService) #

final teamService = UmamiTeamService(endpoint: 'https://your-endpoint.com');

// Create team
final team = await teamService.createTeam(
  token: token,
  name: 'Development Team',
);

// Add user to team
await teamService.addUserToTeam(
  token: token,
  teamId: 'team-id',
  userId: 'user-id',
  role: 'team-member', // 'team-owner', 'team-manager', 'team-member', 'team-view-only'
);

// Get team websites
final websites = await teamService.getTeamWebsites(
  token: token,
  teamId: 'team-id',
);

🌐 Website Management (UmamiWebsiteService) #

final websiteService = UmamiWebsiteService(endpoint: 'https://your-endpoint.com');

// Create website
final website = await websiteService.createWebsite(
  token: token,
  domain: 'myapp.com',
  name: 'My Mobile App',
  teamId: 'team-id', // optional
);

// Get website statistics
final stats = await websiteService.getWebsiteStats(
  token: token,
  websiteId: 'website-id',
  startAt: DateTime.now().subtract(Duration(days: 30)).millisecondsSinceEpoch,
  endAt: DateTime.now().millisecondsSinceEpoch,
);

// Get pageviews over time
final pageviews = await websiteService.getWebsitePageviews(
  token: token,
  websiteId: 'website-id',
  startAt: startTimestamp,
  endAt: endTimestamp,
  unit: 'day', // 'year', 'month', 'hour', 'day'
  timezone: 'Europe/Lisbon',
);

// Get website metrics (pages, referrers, browsers, etc.)
final metrics = await websiteService.getWebsiteMetrics(
  token: token,
  websiteId: 'website-id',
  startAt: startTimestamp,
  endAt: endTimestamp,
  type: 'url', // 'url', 'referrer', 'browser', 'os', 'device', 'country', 'event'
);

📊 Event Tracking (UmamiEventService) #

final eventService = UmamiEventService(endpoint: 'https://your-endpoint.com');

// Get website events
final events = await eventService.getWebsiteEvents(
  token: token,
  websiteId: 'website-id',
  startAt: startTimestamp,
  endAt: endTimestamp,
);

// Get event data with filtering
final filteredEvents = await eventService.getWebsiteEventData(
  token: token,
  websiteId: 'website-id',
  startAt: startTimestamp,
  endAt: endTimestamp,
  eventType: 'custom',
);

🔄 Session Management (UmamiSessionService) #

final sessionService = UmamiSessionService(endpoint: 'https://your-endpoint.com');

// Get website sessions
final sessions = await sessionService.getWebsiteSessions(
  token: token,
  websiteId: 'website-id',
  startAt: startTimestamp,
  endAt: endTimestamp,
);

// Get session activity
final activity = await sessionService.getSessionActivity(
  token: token,
  websiteId: 'website-id',
  startAt: startTimestamp,
  endAt: endTimestamp,
  unit: 'hour',
  timezone: 'UTC',
);

📤 Direct Send Service (UmamiSendService) #

Send events directly without authentication - perfect for public analytics.

final sendService = UmamiSendService(
  website: 'website-id',
  hostname: 'your-app.com',
  endpoint: 'https://cloud.umami.is', // or your self-hosted URL
);

// Send pageview
await sendService.sendPageview(
  context: context,
  title: 'Home Screen',
  url: '/home',
);

// Send custom event
await sendService.sendCustomEvent(
  context: context,
  title: 'Settings',
  url: '/settings',
  name: 'toggle_notifications',
  data: {'enabled': true},
);

🌟 Usage Examples #

Complete Analytics Dashboard #

class AnalyticsDashboard extends StatefulWidget {
  @override
  _AnalyticsDashboardState createState() => _AnalyticsDashboardState();
}

class _AnalyticsDashboardState extends State<AnalyticsDashboard> {
  final websiteService = UmamiWebsiteService(endpoint: 'https://your-endpoint.com');
  String? token;
  Map<String, dynamic>? stats;

  @override
  void initState() {
    super.initState();
    loadAnalytics();
  }

  Future<void> loadAnalytics() async {
    // Assume token is obtained from authentication
    final endTime = DateTime.now();
    final startTime = endTime.subtract(Duration(days: 7));
    
    final analyticsData = await websiteService.getWebsiteStats(
      token: token!,
      websiteId: 'your-website-id',
      startAt: startTime.millisecondsSinceEpoch,
      endAt: endTime.millisecondsSinceEpoch,
    );
    
    setState(() {
      stats = analyticsData;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Analytics Dashboard')),
      body: stats == null
        ? CircularProgressIndicator()
        : Column(
            children: [
              Text('Pageviews: ${stats!['pageviews']}'),
              Text('Visitors: ${stats!['visitors']}'),
              Text('Bounce Rate: ${stats!['bounces']}'),
              // Add charts and more detailed analytics
            ],
          ),
    );
  }
}

Multi-User Team Setup #

Future<void> setupTeamAndWebsite() async {
  final authService = UmamiAuthService(endpoint: 'https://your-endpoint.com');
  final teamService = UmamiTeamService(endpoint: 'https://your-endpoint.com');
  final userService = UmamiUserService(endpoint: 'https://your-endpoint.com');
  final websiteService = UmamiWebsiteService(endpoint: 'https://your-endpoint.com');

  // Login as admin
  final loginResponse = await authService.login(
    username: 'admin',
    password: 'admin-password',
  );
  final token = loginResponse?['token'];

  // Create a team
  final team = await teamService.createTeam(
    token: token!,
    name: 'Mobile Development Team',
  );
  final teamId = team?[0]['id'];

  // Create a user
  final user = await userService.createUser(
    token: token,
    username: 'developer1',
    password: 'dev-password',
    role: 'user',
  );
  final userId = user?['id'];

  // Add user to team
  await teamService.addUserToTeam(
    token: token,
    teamId: teamId,
    userId: userId,
    role: 'team-member',
  );

  // Create website under team
  final website = await websiteService.createWebsite(
    token: token,
    domain: 'myapp.com',
    name: 'My Flutter App',
    teamId: teamId,
  );

  print('Setup complete! Website ID: ${website?['websiteUuid']}');
}

🔧 Configuration #

Environment Variables #

For better security, consider using environment variables:

// .env file
UMAMI_ENDPOINT=https://your-umami-instance.com
UMAMI_WEBSITE_ID=your-website-id
UMAMI_USERNAME=admin
UMAMI_PASSWORD=password

// Usage
final endpoint = dotenv.env['UMAMI_ENDPOINT']!;
final websiteId = dotenv.env['UMAMI_WEBSITE_ID']!;

Error Handling #

All services include comprehensive error handling with detailed JSON error responses:

final result = await websiteService.createWebsite(
  token: invalidToken,
  domain: 'test.com',
  name: 'Test Site',
);

if (result == null) {
  // Check debug console for detailed error information:
  // Failed to create website: 401
  // Error JSON: {"message": "Unauthorized"}
}

🌍 Umami Cloud vs Self-Hosted #

Feature Umami Cloud Self-Hosted
Authentication API Key Username/Password
User Management
Team Management
Website Management Limited
Event Tracking
Analytics Data

For Umami Cloud, use the direct send service or API keys. For self-hosted, you have full access to all management features.

📱 Platform Support #

  • ✅ Android
  • ✅ iOS
  • ✅ Web
  • ✅ Desktop (Windows, macOS, Linux)

🤝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License #

This project is licensed under the MIT License - see the LICENSE file for details.


Made with ❤️ for the Flutter community

2
likes
130
points
56
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for integrating Umami Analytics into your apps. Track navigation and custom events easily, providing privacy-friendly analytics for your users.

Repository

Documentation

API reference

License

MIT (license)

Dependencies

device_info_plus, flutter, http

More

Packages that depend on flutter_estatisticas