Skip to content

Analytics

IAnalyticsUtils is an abstract class designed for handling analytics-related functionalities in an application. Below is a detailed explanation of its structure and functionalities:

Methods and Fields

Abstract Methods:

  • getDefaultEventData(): This method, when implemented, is expected to return a Future. This would typically contain default data that should be added to every analytics event. This could include information like the customer's phone number, device information, app version, etc.
  • getAppSection({required AnalyticsEventEnum event}): This method takes an AnalyticsEventEnum as a parameter and returns an IAppSection. It's responsible for determining the section of the app relevant to a particular analytics event.

Static Fields:

  • _firebaseAnalytics: An optional static field of type FirebaseAnalytics. This is used for integrating Firebase analytics.
  • _mixpanelInstance: An optional static field of type Mixpanel. This is used for Mixpanel analytics integration.
  • analyticsApi: A static field initialized with AnalyticsApi. This is used for making API requests related to analytics.

Initialization Method:

  • init({required String mixpanelToken}): An asynchronous method to initialize analytics tools, specifically Mixpanel with the provided token.

Event Logging Methods:

  • logEvent(...): Logs an analytics event to various platforms based on the specified providers.
  • _logFirebaseEvent(...), _logMixPanelEvent(...), _logEventStoreEvent(...): These are private methods for logging events to specific analytics platforms (Firebase, MixPanel, and a generic event store, respectively).

Utility Methods:

  • recordAnalyticsEvent(...): A public method to log an analytics event.
  • recordAnalyticsEventWithEnum(...): Similar to recordAnalyticsEvent, but it takes an AnalyticsEventEnum as an input and converts it to an AnalyticsEvent.

Example

dart
class AppAnalyticsUtils extends IAnalyticsUtils {
  // Private constructor
  AppAnalyticsUtils._();

  // Singleton instance
  static final AppAnalyticsUtils _instance = AppAnalyticsUtils._();

  // Get accessor to retrieve the singleton instance
  static AppAnalyticsUtils get instance => _instance;

  var appPreferenceManager = AppPreferenceManager();

  @override
  Future<DefaultEventData> getDefaultEventData() async {
    var customer = await appPreferenceManager.getCustomer();
    var sessionId = await appPreferenceManager.getSessionId();
    var deviceInfo = await DeviceHelper.getDeviceInfo();

    var defaultEventData = DefaultEventData(
        customerPhoneNumber: customer?.mobileNumber,
        os: deviceInfo.os,
        osVersion: deviceInfo.osVersion,
        appType: AppType.app,
        time: DateTime.now(),
        appName: 'Hubtel',
        appCategory: 'Customer Apps',
        // TODO: move this to a constant and also fill rest of info,
        sessionId: sessionId,
        appBuildNumber: deviceInfo.appBuildNumber,
        appVersion: deviceInfo.appVersionNumber,
        latitude: null,
        longitude: null,
        station: null,
        zone: null);
    return defaultEventData;
  }

  @override
  IAppSection getAppSection({required AnalyticsEventEnum event}) {
    switch (event.sectionName) {
      case "account":
        return AppSection.account;
      case "airtime_data_and_bills":
        return AppSection.airtimeDataAndBills;
      case "checkout":
        return AppSection.checkout;
      case "event_tickets":
        return AppSection.eventTickets;
      case "food":
        return AppSection.food;
      case "health":
        return AppSection.health;
      case "home":
        return AppSection.home;
      case "insurance":
        return AppSection.insurance;
      case "onboarding":
        return AppSection.onboarding;
      case "send_money":
        return AppSection.sendMoney;
      case "shop":
        return AppSection.shop;
      case "sms_and_money":
        return AppSection.smsAndMoney;
      case "take_payments":
        return AppSection.takePayment;
      default:
        return AppSection.other;
    }
  }
}

Widgets with in-built analytics

Widgets within the application can have built-in analytics capabilities. To achieve this, specific widgets are designed to record analytics events during their initialization phase. Here's an example of how this is implemented:

AppPage Widget with Built-in Analytics The AppPage class, a StatefulWidget, is an example of such a widget. It has the following relevant properties:

  • analyticsEvents: A list of AnalyticsEvent objects.
  • analyticsEventEnums: A list of AnalyticsEventEnum objects.

These properties are used to define the analytics events that should be recorded when the widget is initialized. Here's an example of how these events are recorded in the widget's initializer:

dart
HubtelCoreUX.recordAnalytics(analyticsEvents: widget.analyticsEvents,  analyticsEventEnums: widget.analyticsEventEnums);

Setting Up Analytics in the Host Application

For the analytics to work effectively, the host application that depends on the core-ux package needs to perform some setup, particularly initializing HubtelCoreUX. This initialization should be done in an appropriate place, such as the AppStartup class of the application.

Initializing HubtelCoreUX in AppStartup Here's an example of how the HubtelCoreUX can be initialized:

dart
// Initialize Hubtel Core UX
HubtelCoreUX.initialize(appAnalyticsUtils: AppAnalyticsUtils.instance);

By calling HubtelCoreUX.initialize and passing the instance of AppAnalyticsUtils, the host application sets up the necessary environment for analytics tracking. This ensures that any widget within the application that uses HubtelCoreUX.recordAnalytics will correctly log analytics events.

Building on the previous documentation, we now delve into the implementation of analytics in custom widgets within the application. Custom widgets can directly invoke analytics recording through specific methods provided by the AppAnalyticsUtils class. This allows for a granular tracking of user interactions specific to the functionalities of these custom widgets.

Invoking Analytics in Custom Widgets

Custom widgets can record analytics events using one of the two methods from the AppAnalyticsUtils instance. These methods are:

  • recordAnalyticsEventWithEnum
  • recordAnalyticsEvent

Here's how each method can be used within a custom widget:

Using recordAnalyticsEventWithEnum

This method is particularly useful when you want to record an event that has been predefined as an AnalyticsEventEnum. This approach is often simpler and more structured, as AnalyticsEventEnum typically represents a predefined set of possible events in an enum format.

Example Usage:

dart
AppAnalyticsUtils.instance.recordAnalyticsEventWithEnum(event: HomeEvent.accountHomeTapAccount);

In this example, HomeEvent.accountHomeTapAccount is an enum value representing a specific user interaction event within the home account section of the application.

Using recordAnalyticsEvent

This method is used when you want to record a custom AnalyticsEvent. It offers more flexibility as it allows for the creation of ad-hoc analytics events that might not be predefined in the AnalyticsEventEnum.

Example Usage:

dart
AppAnalyticsUtils.instance.recordAnalyticsEvent(event: HomeEvent.accountHomeTapAccount);

Here, HomeEvent.accountHomeTapAccount is an instance of AnalyticsEvent, allowing for more detailed and specific event tracking.

Conclusion

In summary, the integration of analytics in the core-ux package follows a two-step approach:

Custom widgets:

  • recordAnalyticsEventWithEnum: Best suited for predefined, enum-based analytics events. Offers simplicity and structure.
  • recordAnalyticsEvent: Ideal for more dynamic, custom-defined analytics events. Provides flexibility for detailed event tracking.

Widget-Level Integration: Widgets like AppPage, SearchTextField, HBButton, AppTapContainer are designed to include analytics capabilities by having properties for analytics events and enums. These are recorded during the widget's initialization.

Application-Level Setup: The host application must initialize HubtelCoreUX with an instance of AppAnalyticsUtils to ensure that analytics tracking is properly set up across the application.

This structure provides a flexible and modular approach to incorporating analytics into different parts of an application, enabling detailed tracking and analysis of user interactions and behaviors.