Analytics Hub
This documentation is also available in Ukrainian.
analytics_hub is a small aggregation layer on top of analytics SDKs
such as Firebase, Mixpanel, and custom providers.
Features
- Single event model based on
LogEvent. - One routing entry point via
AnalyticsHub. - Provider targeting through
EventProvider. - Centralized session propagation through
HubSessionDelegate. - Global and provider-level event interceptors.
- Typed event metadata context (
EventContext/ContextEntry).
When you might want it
- You send the same logical event to multiple analytics SDKs.
- You want to decouple domain/UI code from concrete analytics dependencies.
- You need centralized session and configuration management for analytics.
- You want to be able to toggle providers on/off per environment or product.
Current providers (each has its own README with integration steps):
- Firebase: analytics_hub_firebase — log events
- Mixpanel: analytics_hub_mixpanel — log events
- Appsflyer:
analytics_hub_appsflyer— log events viaAppsflyerSdk.logEvent
Installation
In your app pubspec.yaml:
dependencies:
analytics_hub: ^0.4.0
# and then any concrete providers you need, e.g.:
# analytics_hub_firebase: ^0.4.0
# analytics_hub_mixpanel: ^0.4.0
# analytics_hub_appsflyer: ^0.4.0
Core concepts
AnalyticsHub– the facade you use to send events.Event– base class for events sent by the hub.LogEvent– simplename + propertiesevent.AnalytycsProvider– abstraction of an analytics provider.EventResolver– provider event handling contract.ProviderIdentifier– identifies a provider; events list targets viaEventProvider.Session/HubSessionDelegate– session model plus a delegate that supplies the current session and a stream of session changes.EventInterceptor– middleware that can transform or drop event dispatches.EventDispatchContext– runtime context available inside interceptors and resolvers.
Event model
Only LogEvent is supported by core.
namedefines the event key.propertiescontains optional payload (Map<String, Object?>?).providersdefines which registered providers should receive the event.contextcontains typed metadata available during interception and resolving.
Defining events
class ScreenViewEvent extends LogEvent {
const ScreenViewEvent({
required this.screenName,
required this.screenClass,
}) : super(
'screen_view',
context: const EventContext().withEntry(
const FeatureContextEntry('navigation'),
),
);
final String screenName;
final Type screenClass;
@override
Map<String, Object?> get properties => {
'screen_name': screenName,
'screen_class': screenClass.toString(),
};
@override
List<EventProvider> get providers => [
const EventProvider(BackendAnalyticsProviderIdentifier()),
];
}
final class FeatureContextEntry extends ContextEntry {
const FeatureContextEntry(this.feature);
final String feature;
}
Implementing your own provider (step‑by‑step)
A custom provider (e.g. sending events to your backend) consists of:
- Provider identifier (
ProviderIdentifier). - Event resolver (
EventResolver). - Provider class (
AnalytycsProvider) registered inAnalyticsHub.
1. Provider identifier (ProviderIdentifier)
import 'package:analytics_hub/analytics_hub.dart';
class BackendAnalyticsProviderIdentifier
extends ProviderIdentifier {
const BackendAnalyticsProviderIdentifier({super.name});
}
2. Event resolver (EventResolver)
import 'package:analytics_hub/analytics_hub.dart';
class BackendEventResolver
implements EventResolver {
const BackendEventResolver();
@override
Future<void> resolve(
ResolvedEvent event, {
required EventDispatchContext context,
}) async {
// e.g. POST event.name + event.properties to your backend.
// context has event metadata and correlationId for tracing.
}
}
3. Provider class (AnalytycsProvider)
import 'package:analytics_hub/analytics_hub.dart';
class BackendAnalyticsProvider
extends AnalytycsProvider {
BackendAnalyticsProvider({String? name})
: super(
identifier: BackendAnalyticsProviderIdentifier(name: name),
interceptors: const [],
);
@override
BackendEventResolver get resolver => const BackendEventResolver();
@override
Future<void> initialize() async {
// e.g. create HTTP client, auth headers
}
@override
Future<void> setSession(Session? session) async {
// e.g. send session.id to backend for user association
}
@override
Future<void> dispose() async {
// close HTTP client, etc.
}
}
Important details:
identifiermust uniquely identify this provider instance (type + name).resolvercan be cached or created on demand.setSessionis called whenever the session changes (HubSessionDelegate.sessionStream).initialize/flush/disposehelp you manage provider lifecycle.
4. Registering the provider in AnalyticsHub
final hub = AnalyticsHub(
sessionDelegate: yourSessionDelegate,
providers: [
BackendAnalyticsProvider(),
],
);
await hub.initialize();
await hub.sendEvent(
ScreenViewEvent(
screenName: 'settings',
screenClass: SettingsScreen,
),
);
await hub.flush();
Any event that includes BackendAnalyticsProviderIdentifier in providers
will be routed to your provider.
When to create your own provider
- You have an in‑house analytics system (logging service, data pipeline, etc.).
- You need to support another 3rd‑party SDK that doesn’t have a ready‑made package.
- You want to wrap a complex SDK behind a simple resolver, so the rest of the app never talks to that SDK directly.
Interceptors
Use interceptors for cross-cutting behavior (renaming events, redaction, sampling).
final class PrefixInterceptor implements EventInterceptor {
const PrefixInterceptor(this.prefix);
final String prefix;
@override
FutureOr<InterceptorResult> intercept({
required ResolvedEvent event,
required EventDispatchContext context,
required NextEventInterceptor next,
}) {
return next(
event.copyWith(name: '${prefix}_${event.name}'),
context,
);
}
}
final hub = AnalyticsHub(
sessionDelegate: yourSessionDelegate,
providers: [BackendAnalyticsProvider()],
interceptors: [const PrefixInterceptor('prod')],
);
More information
- Core example:
example/main.dart. - Firebase and Mixpanel providers are in sibling packages in this repository.
Suggestions and improvements
Have an idea to improve Analytics Hub or one of the providers? We’d love to hear it. Please open an issue in the repository with your suggestion or feedback.
Libraries
- analytics_hub
- Analytics Hub — a unified analytics abstraction for Dart/Flutter apps.