infobits 0.1.1 copy "infobits: ^0.1.1" to clipboard
infobits: ^0.1.1 copied to clipboard

Infobits analytics and error tracking. Analytics, Logging, Logger, Error Tracking, Crash Reporting, Performance Monitoring, and more.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:infobits/infobits.dart';

void main() {
  // Run app with Infobits initialization and error handling
  runWithInfobits(
    app: const MyApp(),
    apiKey: 'your-api-key-here',
    // domain is optional - will be extracted from package name if not provided
    // domain: 'example.app',  // You can still override it if needed
    debug: true,
    onError: (error, stack) {
      // Optional: Additional custom error handling
      // The error has already been logged to Infobits
      // You can add custom logic here like showing a dialog,
      // sending to another service, etc.
    },
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Infobits Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
      navigatorObservers: [InfobitsAnalyticsObserver()],
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _counter = 0;

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

    // Safe initialization checks
    if (Infobits.canTrack) {
      InfobitsAnalytics.instance.startView('/home');
    }

    if (Infobits.canLog) {
      Logger.info('HomePage initialized');
      Logger.debug(
        'Infobits status - Initialized: ${Infobits.isInitialized}, Can log: ${Infobits.canLog}, Can track: ${Infobits.canTrack}',
      );
    }
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });

    // Track custom analytics event (using startView as a workaround)
    InfobitsAnalytics.instance.startView(
      '/events/button_click?value=$_counter',
    );

    // Log the action
    Logger.debug('Counter incremented to $_counter');
  }

  void _triggerError() {
    try {
      // Intentionally trigger an error for demonstration
      throw Exception('This is a test error for demonstration purposes');
    } catch (e, stackTrace) {
      Logger.error(
        'Error triggered',
        exception: e,
        information: stackTrace.toString(),
      );

      // Also track as an analytics event
      InfobitsAnalytics.instance.startView('/events/error_triggered');
    }
  }

  void _testLoggingLevels() {
    // Check if logging is available before using it
    if (Infobits.canLog) {
      Logger.verbose('This is a verbose message');
      Logger.debug('This is a debug message');
      Logger.info('This is an info message');
      Logger.warn('This is a warning message');
      Logger.error('This is an error message');
      Logger.fatal('This is a fatal message');
    } else {
      // Fallback if Infobits is not initialized
      debugPrint('Infobits logging is not available');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('Infobits Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'Infobits Package Demo',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 20),
            const Text('You have pushed the button this many times:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            const SizedBox(height: 40),
            ElevatedButton.icon(
              onPressed: _testLoggingLevels,
              icon: const Icon(Icons.list),
              label: const Text('Test Logging Levels'),
            ),
            const SizedBox(height: 10),
            ElevatedButton.icon(
              onPressed: _triggerError,
              icon: const Icon(Icons.error_outline),
              label: const Text('Trigger Test Error'),
            ),
            const SizedBox(height: 10),
            ElevatedButton.icon(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const SecondPage(),
                    settings: const RouteSettings(name: '/second'),
                  ),
                );
              },
              icon: const Icon(Icons.navigate_next),
              label: const Text('Navigate to Second Page'),
            ),
            const SizedBox(height: 10),
            ElevatedButton.icon(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => const AnalyticsPage(),
                    settings: const RouteSettings(name: '/analytics'),
                  ),
                );
              },
              icon: const Icon(Icons.analytics),
              label: const Text('Analytics Demo'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }

  @override
  void dispose() {
    InfobitsAnalytics.instance.endView('/home');
    super.dispose();
  }
}

class SecondPage extends StatefulWidget {
  const SecondPage({super.key});

  @override
  State<SecondPage> createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  @override
  void initState() {
    super.initState();
    Logger.info('SecondPage opened');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Second Page')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'This is the second page',
              style: TextStyle(fontSize: 20),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                Logger.debug('Navigating back from SecondPage');
                Navigator.pop(context);
              },
              child: const Text('Go Back'),
            ),
          ],
        ),
      ),
    );
  }
}

class AnalyticsPage extends StatefulWidget {
  const AnalyticsPage({super.key});

  @override
  State<AnalyticsPage> createState() => _AnalyticsPageState();
}

class _AnalyticsPageState extends State<AnalyticsPage> {
  final TextEditingController _eventNameController = TextEditingController();
  final TextEditingController _propertyValueController =
      TextEditingController();

  void _trackCustomEvent() {
    final eventName = _eventNameController.text.trim();
    final propertyValue = _propertyValueController.text.trim();

    if (eventName.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Please enter an event name')),
      );
      return;
    }

    // Use startView to track custom events
    String eventPath = '/events/$eventName';
    if (propertyValue.isNotEmpty) {
      eventPath += '?value=$propertyValue';
    }

    InfobitsAnalytics.instance.startView(eventPath);
    Logger.info('Custom event tracked: $eventName', information: propertyValue);

    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text('Event "$eventName" tracked!')));

    // Clear fields
    _eventNameController.clear();
    _propertyValueController.clear();
  }

  @override
  void dispose() {
    _eventNameController.dispose();
    _propertyValueController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Analytics Demo')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text(
              'Track Custom Event',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 20),
            TextField(
              controller: _eventNameController,
              decoration: const InputDecoration(
                labelText: 'Event Name',
                border: OutlineInputBorder(),
                hintText: 'e.g., user_signup',
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: _propertyValueController,
              decoration: const InputDecoration(
                labelText: 'Property Value (optional)',
                border: OutlineInputBorder(),
                hintText: 'e.g., premium',
              ),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _trackCustomEvent,
              child: const Text('Track Event'),
            ),
            const SizedBox(height: 40),
            const Text(
              'Pre-defined Events',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 10),
            Wrap(
              spacing: 10,
              runSpacing: 10,
              children: [
                ElevatedButton(
                  onPressed: () {
                    InfobitsAnalytics.instance.startView('/events/app_opened');
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(content: Text('Tracked: app_opened')),
                    );
                  },
                  child: const Text('App Opened'),
                ),
                ElevatedButton(
                  onPressed: () {
                    InfobitsAnalytics.instance.startView(
                      '/events/purchase?amount=99.99&currency=USD',
                    );
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(content: Text('Tracked: purchase')),
                    );
                  },
                  child: const Text('Purchase'),
                ),
                ElevatedButton(
                  onPressed: () {
                    InfobitsAnalytics.instance.startView(
                      '/events/share?platform=twitter&content=article',
                    );
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(content: Text('Tracked: share')),
                    );
                  },
                  child: const Text('Share'),
                ),
                ElevatedButton(
                  onPressed: () {
                    // Test crash functionality (commented out for safety)
                    // InfobitsLogging.instance.crash('Test crash from example app');
                    Logger.fatal(
                      'Simulated fatal error',
                      exception: 'User triggered fatal log',
                    );
                    ScaffoldMessenger.of(context).showSnackBar(
                      const SnackBar(
                        content: Text('Fatal error logged (app not crashed)'),
                      ),
                    );
                  },
                  child: const Text('Log Fatal Error'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
15
downloads

Publisher

verified publisherinfobits.io

Weekly Downloads

Infobits analytics and error tracking. Analytics, Logging, Logger, Error Tracking, Crash Reporting, Performance Monitoring, and more.

Homepage
Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

device_info_plus, flutter, grpc, http, package_info_plus, stack_trace

More

Packages that depend on infobits