Представьте себе ситуацию: вы рассказали всем своим родным и близким о своем замечательном новом приложении. Возможно, вам даже посчастливилось сформировать список ожидания из заинтересованных пользователей. Вы сгораете от нетерпения нажать кнопку «Publish».
Но погодите минутку…
А как вы узнаете, что действительно работает, а что нуждается в улучшении?
Сколько пользователей завершили онбординг?
Сколько пользователей зарегистрировались и создали учетную запись?
Сколько пользователей достигли пейвола и сколько конвертировались?
Без аналитики вы действуете вслепую.
Вы принимаете решения о продукте, основываясь на предположениях, а не на данных. Это самый простой способ замедлить ваш рост, потратить впустую время разработки или, что еще хуже, потерять пользователей.
Важность аналитики
Аналитика предоставляет вам данные, необходимые для достижения успеха. Она помогает вам:
Измерять вовлеченность: Кто использует ваше приложение, как часто и как долго?
Понимать ретеншн: Где пользователи отваливаются и почему?
Отслеживать использование функций: Что популярно? Что игнорируется?
Оптимизировать прибыль: Отслеживание покупок, подписок и оттока.
Знать своих пользователей: Демография, устройства, платформы.
Контролировать пользовательский опыт: Составление карты пользовательского опыта и выявление проблемных областей.
Получив эту информацию вы перестанете гадать и начнете принимать обоснованные решения о продукте, которые действительно улучшат ваше приложение.

Чему вы научитесь
В этой статье я покажу вам, как эффективно отслеживать аналитику в вашем Flutter‑приложении — от базового логирования событий до масштабируемой архитектуры, которая будет работать с разными системами, такими как Firebase и Mixpanel.
Ключевые моменты, которые мы рассмотрим:
Что стоит отслеживать: Выбор ключевых событий и их значимость.
Как структурировать аналитику: Простые и масштабируемые архитектуры для отслеживания событий.
Настройка Firebase Analytics: Как настроить аналитику в реальном приложении.
Что ж, давайте приступим.
Эта статья познакомит вас с основами. Если вы хотите углубить свои знания, я рекомендую ознакомиться с курсом "Flutter Mobile Developer".
Введение в отслеживание событий
Если вы спросите пять разных разработчиков, как они внедрили аналитику, вы, вероятно, получите пять разных ответов.
Как это часто бывает в программной инженерии, не существует универсального решения — только компромиссы.
Поэтому, прежде чем мы углубимся в код, давайте немного отдалимся и ответим на несколько ключевых вопросов:
Какие события нам следует отслеживать?
Как мы должны их отслеживать?
Каким требованиям должно соответствовать наше решение?
Как только мы разберемся с этим, мы сможем выбрать подходящую архитектуру.
Какие события нам нужно отслеживать?
Говоря простым языком, события представляют собой взаимодействия между пользователем и вашим приложением.
Давайте рассмотрим в качестве примера мое приложение Flutter Ship:
Демо‑версия приложения Flutter Ship
Приложение поможет вам «поставить все галочки» перед выпуском приложений Flutter. По сути, это предварительно заполненный список дел.
Задача этого приложения заключается в том, чтобы помочь вам выполнить все необходимые шаги перед релизом ваших Flutter‑приложений. По сути, это просто готовый список задач: https://bizz84.github.io/flutter_ship_app_web/#apps [Откройте в отдельном окне]
Если бы вам нужно было добавить аналитику в это приложение, какие события вы бы отслеживали?
Важно сосредоточиться на событиях, которые:
Помогают пользователю добиться успеха (например, выполнить задачи)
Способствуют успеху вашего бизнеса (например, регистрация пользователей, ретеншн, монетизация)
Для этого приложения значимыми событиями являются:
Создание нового приложения
Внесение изменений в существующее приложение
Удаление приложения
Выполнение задачи
Остальные события не являются обязательными для отслеживания. Не стоит отслеживать все подряд только потому что вы можете это сделать.
Отслеживание событий с помощью Firebase Analytics и Mixpanel
Теперь давайте рассмотрим, как вы можете отслеживать различные события в своем Flutter‑приложении.
Если вы используете пакет firebase_analytics
, вы можете реализовать это следующим образом:
final analytics = FirebaseAnalytics.instance;
analytics.logEvent('app_created');
analytics.logEvent('app_updated');
analytics.logEvent('app_deleted');
analytics.logEvent('task_completed', parameters: {'count': count});
Или, если вы предпочитаете пакет mixpanel_flutter
, то это может выглядеть так:
final mixpanel = await Mixpanel.init(
Env.mixpanelProjectToken,
trackAutomaticEvents: true,
);
mixpanel.track('App Created');
mixpanel.track('App Updated');
mixpanel.track('App Deleted');
mixpanel.track('Task Completed', properties: {'count': count});
Проблема сразу же бросается в глаза: разные API — разный синтаксис.
❌ Разбрасывать эти вызовы по всей вашей кодовой базе — не лучшая идея. ❌
Давайте разберемся, почему:
Вы привязываете себя к определенным SDK
Вы повсюду дублируете названия событий (легко сделать опечатку, трудно рефакторить)
Вы теряете типобезопасность и поддержку IDE
Вы не можете повторно использовать логику или отправлять события сразу нескольким вендорам
Вы смешиваете бизнес‑логику с деталями реализации
Мы можем добиться гораздо большего, если определим четкий интерфейс, который отделит отслеживание событий от всего остального.
Но для этого нам потребуется сформировать список требований.
Аналитика приложения: Требования
Прежде чем приступить к реализации, давайте четко сформулируем требования к аналитической системе.
Ниже представлен ряд ключевых требований, которые нам необходимо учесть:
Разделение ответственности: Код приложения не должен напрямую взаимодействовать с SDK‑пакетами вендоров (например, Firebase или Mixpanel). Вместо этого все отслеживание событий будет происходить через простой и понятный интерфейс.
Поддержка нескольких клиентов: Нам необходимо иметь возможность отправлять события сразу нескольким вендорам. Например, мы можем захотеть реализовать логирование одновременно в Firebase и Mixpanel.
Отдельные режимы для отладочной и релизной сборки: Во время разработки в большинстве ситуаций мы хотим отражать события только в консоли. В релизной сборке же следует использовать реальных вендоров аналитики — без изменений логики приложения.
Другие важные вещи, о которых стоит задуматься:
Отслеживание переходов между экраннами
Переключение между активным и неактивным режимами (например, из соображений конфиденциальности / GDPR)
Идентификация пользователя (после входа в систему)
Несколько вариантов сборки (dev/staging/prod)
Но сейчас мы сосредоточимся на двух наиболее важных моментах:
Изоляция аналитики от логики приложения
Поддержка нескольких вендоров аналитики
Давайте рассмотрим две возможные архитектуры и разберем их компромиссы.
Простейшая архитектура аналитики
Этот сетап был разработан мной на основе предложения, которое я получил в X (Twitter):
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:mixpanel_flutter/mixpanel_flutter.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
class AnalyticsClient {
const AnalyticsClient(this._analytics, this._mixpanel);
final FirebaseAnalytics _analytics;
final Mixpanel _mixpanel;
Future<void> track(
String name, {
Map<String, dynamic> params = const {},
}) async {
if (kReleaseMode) {
await _analytics.logEvent(name: name, parameters: params);
await _mixpanel.track(name, properties: params);
} else {
log('$name $params', name: 'Event');
}
}
}
Проще некуда. Это минималистичный общий интерфейс для отслеживания событий:
В релизной сборке он отправляет события и в Firebase, и в Mixpanel
В режиме отладки они просто выводятся в консоль.
Если вы используете Riverpod, отслеживание событий выглядит следующим образом:
final analytics = ref.read(analyticsClientProvider);
analytics.track('app_created');
analytics.track('app_updated');
analytics.track('app_deleted');
analytics.track('task_completed', parameters: {'count': count});
Если названия ваших событий соответствуют рекомендациям Firebase Analytics (от 1 до 40 буквенно‑цифровых символов с нижними подчеркиваниями), то вам больше не о чем беспокоиться.
Этот подход на удивление гибок, учитывая, как мало кода он требует. Вы можете легко сменить вендоров аналитики, обновив всего лишь один класс, и при этом остальные части вашего приложения останутся нетронутыми.
Но у нее есть недостатки
Которые начинают проявляться по мере роста вашего приложения:
Отсутствие условного отслеживания: Вы не можете выборочно отправлять некоторые события в Mixpanel, но не в Firebase. Это может стать проблемой, если вам нужно следить за объемом отправляемых событий (и их стоимостью).
Повсюду сплошной хардкод: Имена событий в конечном итоге дублируются по всей кодовой базе. Легко опечатку. Сложно рефакторить. Большие грабли с точки зрения командной работы.
Нет единого источника истины: Нет централизованного списка событий или их ожидаемых параметров.
Нет автозаполнения: Вы теряете поддержку IDE. Если бы у вас был типобезопасный API, то вы могли бы наслаждаться автозаполнением:

Этот сетап может быть достаточно хорош для инди‑разработчиков или небольших приложений, где требуется полный контроль и минимум сложностей.
Однако, если вы работаете с более крупной кодовой базой или в составе команды, то стоит инвестировать во что‑то более серьезное. Давайте рассмотрим более масштабируемую альтернативу.
Архитектура аналитики посложнее
Если вам нужен типобезопасный API аналитики с автозаполнением и четким разделением ответственности, я рекомендую следующий подход.
Начнем с определения абстрактного интерфейса AnalyticsClient. Для приложения Flutter Ship это может выглядеть следующим образом:
abstract class AnalyticsClient {
Future<void> trackAppCreated();
Future<void> trackAppUpdated();
Future<void> trackAppDeleted();
Future<void> trackTaskCompleted(int completedCount);
}
Таким образом, все события будут определяться в одном месте, что позволит избежать дублирования и потенциальных ошибок.
Но как нам реализовать поддержку нескольких клиентов?
Вот один из способов структурировать это:

Как это работает:
Мы определяем все наши события в абстрактном интерфейсе
AnalyticsClient
.Каждая конкретная реализация (например,
LoggerAnalyticsClient
,FirebaseAnalyticsClient
и т. д.) определяет, как регистрируются эти события.Класс
AnalyticsFacade
также реализует интерфейсAnalyticsClient
, но его задача — просто отправлять события всем зарегистрированным клиентам.Наконец, приложение использует
analyticsFacadeProvider
для доступа к фасаду и вызова соответствующих методов отслеживания.
Теперь, чтобы отслеживать события из кода вашего приложения, достаточно просто добавить:
final analytics = ref.read(analyticsFacadeProvider);
analytics.trackEditApp();
Поскольку каждое событие представлено отдельным методом, вы также получаете типобезопасность и автозаполнение:

Как нам реализовать эту архитектуру?
Пока это всего лишь высокоуровневая архитектура. Чтобы заставить ее работать, нам нужно ответить на три важных вопроса:
Как нам зарегистрировать нескольких клиентов в
AnalyticsFacade
?Как отправлять события каждому клиенту?
Как выглядят конкретные подклассы
AnalyticsClient
?
Далее давайте рассмотрим детали реализации.
Аналитика приложения: детали реализации
Чтобы реализовать архитектуру, о которой мы говорили ранее, нам потребуется несколько ключевых компонентов:
Интерфейс
AnalyticsClient
, который определяет все события, которые мы хотим отслеживать.AnalyticsFacade
, который реализуетAnalyticsClient
и делегирует вызовы нескольким клиентам.LoggerAnalyticsClient
для локальной разработки — отправляет события в консоль.Дополнительные клиенты, такие как
FirebaseAnalyticsClient
,MixpanelAnalyticsClient
и т. д., которые используют SDK от соответствующего вендора.
Для организации всего этого кода я рекомендую разместить его в отдельной папке monitoring
:
‣ lib
‣ src
‣ monitoring
‣ analytics_client.dart
‣ analytics_facade.dart
‣ logger_analytics_client.dart
‣ firebase_analytics_client.dart
Вот как работает каждая часть:
1. Интерфейс AnalyticsClient
Это контракт, который описывает все события, поддерживаемые вашим приложением.
abstract class AnalyticsClient {
// Custom events for the Flutter Ship app.
// TODO: Replace with your own events.
Future<void> trackNewAppOnboarding();
Future<void> trackNewAppHome();
Future<void> trackAppCreated();
Future<void> trackAppUpdated();
Future<void> trackAppDeleted();
Future<void> trackTaskCompleted(int completedCount);
}
Поскольку этот класс является абстрактным, все методы представляют собой только объявления, без реализации.
2. Класс LoggerAnalyticsClient
Тут все просто: этот класс просто отправляет события в консоль. Он полезен для локальной разработки и тестов, прежде чем мы подключим реальный серверный модуль аналитики.
import 'dart:async';
import 'dart:developer';
import 'package:flutter_ship_app/src/monitoring/analytics_client.dart';
class LoggerAnalyticsClient implements AnalyticsClient {
const LoggerAnalyticsClient();
static const _name = 'Event';
@override
Future<void> trackNewAppHome() async {
log('trackNewAppHome', name: _name);
}
@override
Future<void> trackNewAppOnboarding() async {
log('trackNewAppOnboarding', name: _name);
}
@override
Future<void> trackAppCreated() async {
log('trackAppCreated', name: _name);
}
@override
Future<void> trackAppUpdated() async {
log('trackAppUpdated', name: _name);
}
@override
Future<void> trackAppDeleted() async {
log('trackAppDeleted', name: _name);
}
@override
Future<void> trackTaskCompleted(int completedCount) async {
log('trackTaskCompleted(completedCount: $completedCount)', name: _name);
}
}
Мы добавим FirebaseAnalyticsClient
позже. Сейчас сосредоточьтесь на том, что вы хотите отслеживать, а не на том, как это будет отправляться.
Существует ли лучший способ определения событий?
Наш текущий подход работает, но он не очень удобен, так как требует много копипаста для добавления новых событий:
// copy-paste when creating new events
@override
Future<void> trackAppCreated() async {
log('trackAppCreated', name: _name);
}
Следует упомянуть несколько альтернативных вариантов:
Перечисления: Определить перечисление (enum)
AppEvent
, в котором в виде значений будут перечислены все возможные виды событий. Этот вариант не подойдет, если разным событиям нужны разные аргументы.Sealed классы: Использовать базовый sealed класс
AppEvent
и создавать подкласс каждый раз, когда нам нужно добавить новое событие. Это более гибкий подход, но требует больше кода.Union‑типы freezed: Лаконичный синтаксис и паттернматчинг, но требуется кодогенерации.
Каждый из этих вариантов имеет свои преимущества и недостатки. На данный момент мы будем придерживаться нашего первоначального подхода.
3. Класс AnalyticsFacade
AnalyticsFacade
реализует интерфейс AnalyticsClient
. Этот класс отвечает за пересылку вызовов методов всем зарегистрированным клиентам.
import 'package:flutter/foundation.dart';
import 'package:flutter_ship_app/src/monitoring/analytics_client.dart';
import 'package:flutter_ship_app/src/monitoring/logger_analytics_client.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'analytics_facade.g.dart';
// https://refactoring.guru/design-patterns/facade
class AnalyticsFacade implements AnalyticsClient {
const AnalyticsFacade(this.clients);
final List<AnalyticsClient> clients;
@override
Future<void> trackAppOpened() => _dispatch(
(c) => c.trackAppOpened(),
);
@override
Future<void> trackNewAppHome() => _dispatch(
(c) => c.trackNewAppHome(),
);
@override
Future<void> trackNewAppOnboarding() => _dispatch(
(c) => c.trackNewAppOnboarding(),
);
@override
Future<void> trackAppCreated() => _dispatch(
(c) => c.trackAppCreated(),
);
@override
Future<void> trackAppUpdated() => _dispatch(
(c) => c.trackAppUpdated(),
);
@override
Future<void> trackAppDeleted() => _dispatch(
(c) => c.trackAppDeleted(),
);
@override
Future<void> trackTaskCompleted(int completedCount) => _dispatch(
(c) => c.trackTaskCompleted(completedCount),
);
Future<void> _dispatch(
Future<void> Function(AnalyticsClient client) work,
) async {
for (final client in clients) {
await work(client);
}
}
}
Метод _dispatch
уменьшает дублирование кода и транслирует каждое событие всем зарегистрированным клиентам.
Настройка провайдера
Вот как можно отобразить AnalyticsFacade
с помощью Riverpod:
@Riverpod(keepAlive: true)
AnalyticsFacade analyticsFacade(Ref ref) {
return const AnalyticsFacade([
if (!kReleaseMode) LoggerAnalyticsClient(),
]);
}
В отладочных сборках у нас будет логирование в консоль. В релизных сборках мы можем добавлять реальных клиентов, таких как FirebaseAnalyticsClient
(подробнее об этом позже).
Этот сетап предоставляет нам понятный, модульный и масштабируемый способ отслеживания событий аналитики — без привязки логики нашего приложения к какому‑либо SDK конкретного вендора.
Какая архитектура лучше?
Архитектура, которую мы только что создали, дает нам:
Типобезопасный API отслеживания событий
Автозаполнение и поддержка IDE
Четкое разделение обязанностей
Поддержка нескольких серверов аналитики
Вот визуальное представление:

Она гибкая, масштабируемая и готовая к работе в продакшене.
Однако за эту гибкость и масштабируемость приходится платить.
Каждый раз, когда вы добавляете новое событие, вам необходимо:
Добавить новый метод в интерфейс
AnalyticsClient
Реализовать его в
AnalyticsFacade
Реализовать его для каждого конкретного клиента (например, Logger, Firebase, Mixpanel)
Когда может быть достаточно простого подхода
Для небольших приложений или MVP может быть достаточно более простого подхода:
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:mixpanel_flutter/mixpanel_flutter.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
class AnalyticsClient {
const AnalyticsClient(this._analytics, this._mixpanel);
final FirebaseAnalytics _analytics;
final Mixpanel _mixpanel;
Future<void> track(
String name, {
Map<String, dynamic> params = const {},
}) async {
if (kReleaseMode) {
await _analytics.logEvent(name: name, parameters: params);
await _mixpanel.track(name, properties: params);
} else {
log('$name $params', name: 'Event');
}
}
}
Такой подход позволяет быстро реализовать аналитику, но при этом вы теряете важные преимущества:
Автозаполнение
Типобезопасность
Централизованные определения событий
Контроль и фильтрация на уровне вендора

В итоге: Если вы разрабатываете что‑то более серьезное, чем просто одноразовый прототип, то стоит обратить внимание на более структурированную архитектуру. Хотя она может показаться более сложной в реализации, она окупится лучшей поддерживаемостью, удобством в тестировании и общим опытом разработки.
Давайте теперь посмотрим, как можно использовать analyticsFacadeProvider
для отслеживания событий в реальном коде приложения.
Отслеживание пользовательских Событий
Мы определили интерфейс следующим образом:
abstract class AnalyticsClient {
Future<void> trackNewAppOnboarding();
Future<void> trackNewAppHome();
Future<void> trackAppCreated();
Future<void> trackAppUpdated();
Future<void> trackAppDeleted();
Future<void> trackTaskCompleted(int completedCount);
}
Однако, если мы не будем вызывать эти методы, то ничего не будет происходить.
Итак, где нам следует разместить эти вызовы?
В виджетах?
В контроллерах?
Где‑нибудь в другом месте?
Давайте рассмотрим оба варианта.
Отслеживание событий в виджетах и контроллерах
Вот простой пример — кнопка +
на главной странице:

Код отслеживания событий выглядит следующим образом:
IconButton(
onPressed: () {
// event tracking code
unawaited(ref.read(analyticsFacadeProvider).trackNewAppHome());
// navigation code
Navigator.of(context).pushNamed(AppRoutes.createApp);
},
icon: Icon(Icons.add),
)
В этом случае вызов аналитики помещается непосредственно в коллбек onPressed
.
? Функция unawaited
используется здесь для отправки события без блокирования выполнения. Это fire‑and‑forget вызовы — вам не нужно ждать их завершения. Подробнее об этом можно почитать здесь: Используйте unawaited для своих вызовов аналитики .
Однако, если ваша логика более сложная, рекомендуется перенести вызовы аналитики в контроллер.
Вот пример пользовательского класса контроллера:
/// This class holds the business logic for creating, editing, and deleting apps
/// using the underlying AppDatabase class for data persistence.
/// More info here: https://codewithandrea.com/articles/flutter-presentation-layer/
@riverpod
class CreateEditAppController extends _$CreateEditAppController {
@override
void build() {
// no-op
}
Future<void> createOrEditApp(App? existingApp, String newName) async {
final db = ref.read(appDatabaseProvider);
// * Update the DB
if (existingApp != null) {
await db.editAppName(appId: existingApp.id, newName: newName);
} else {
await db.createNewApp(name: newName);
}
// * Analytics code
if (existingApp != null) {
unawaited(ref.read(analyticsFacadeProvider).trackAppUpdated());
} else {
unawaited(ref.read(analyticsFacadeProvider).trackAppCreated());
}
}
Future<void> deleteAppById(int appId) async {
await ref.read(appDatabaseProvider).deleteAppById(appId);
ref.read(analyticsFacadeProvider).trackAppDeleted();
}
}
Этот контроллер отвечает за все изменения и взаимодействия с базой данных, что делает его идеальным местом для отслеживания связанных событий аналитики.
Рекомендации по отслеживанию событий
❌ Никогда не добавляйте отслеживание событий в
build()
. Эта функция может вызываться десятки раз в секунду во время анимаций. То же самое касаетсяinitState()
и других методов жизненного цикла.✅ Добавляйте отслеживание в колбеки виджетов типа
onPressed
. Если логика сложная, перенесите ее в контроллер или служебный класс.✅ Идеальным вариантом для отслеживания событий являются контроллеры. В них нет логики пользовательского интерфейса, их проще тестировать, и в них уже заложена логика, которая инициирует события.
❌ Не отслеживайте события на уровне данных или сетей. События должны отслеживаться в источнике (уровень пользовательского интерфейса) для большей точности.
✅ Используйте
unawaited()
для всех вызовов аналитики. Это позволит вам не блокировать пользовательский интерфейс и не заботиться о результатах — просто запустите и забудьте.
Интеграция Firebase
До сих пор мы использовали LoggerAnalyticsClient
для вывода событий в консоль.
Однако для производственных приложений вам потребуется интеграция с реальной серверной аналитикой, такой как Firebase Analytics, Mixpanel или PostHog.
Благодаря нашему AnalyticsFacade
мы можем легко справиться с этой задачей, не меняя код нашего приложения. Мы просто добавим новый клиент, зарегистрируем его, и все готово. В этом и заключается сила разделения ответственности.
Давайте рассмотрим процесс интеграции Firebase Analytics.
Добавление Firebase в наше Flutter-приложение
Официальное руководство очень хорошо объясняет процесс добавления Firebase в наше Flutter‑приложение.
Если ваше приложение поддерживает несколько вариантов сборок (например, dev, staging, prod), настройка может потребовать от вас дополнительных шагов. Я уже рассказывал об этом в другой статье:
Создание класса FirebaseAnalyticsClient
Это достаточно простая реализация интерфейса AnalyticsClient с использованием Firebase SDK:
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter_ship_app/src/monitoring/analytics_client.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'firebase_analytics_client.g.dart';
class FirebaseAnalyticsClient implements AnalyticsClient {
const FirebaseAnalyticsClient(this._analytics);
final FirebaseAnalytics _analytics;
@override
Future<void> trackNewAppHome() async {
await _analytics.logEvent(name: 'new_app_home');
}
@override
Future<void> trackNewAppOnboarding() async {
await _analytics.logEvent(name: 'new_app_onboarding');
}
@override
Future<void> trackAppCreated() async {
await _analytics.logEvent(name: 'app_created');
}
@override
Future<void> trackAppUpdated() async {
await _analytics.logEvent(name: 'app_updated');
}
@override
Future<void> trackAppDeleted() async {
await _analytics.logEvent(name: 'app_deleted');
}
@override
Future<void> trackTaskCompleted(int completedCount) async {
await _analytics.logEvent(
name: 'task_completed',
parameters: {'count': completedCount},
);
}
}
@Riverpod(keepAlive: true)
FirebaseAnalyticsClient firebaseAnalyticsClient(Ref ref) {
return FirebaseAnalyticsClient(FirebaseAnalytics.instance);
}
Регистрация клиента в фасаде
Чтобы добавить клиент Firebase, обновите свой analyticsFacadeProvider
следующим образом:
@Riverpod(keepAlive: true)
AnalyticsFacade analyticsFacade(Ref ref) {
final firebaseAnalyticsClient = ref.watch(firebaseAnalyticsClientProvider);
return AnalyticsFacade([
firebaseAnalyticsClient,
if (!kReleaseMode) const LoggerAnalyticsClient(),
]);
}
И вот так, без каких‑либо изменений в остальной части вашего приложения, ваши события теперь отправляются в Firebase Analytics.
Вы можете увидеть, как они отображаются в консоли Firebase:

Вот как это выглядит в моем приложении Flutter Tips:

Аналитика Flutter-приложений: Заключение
В этой статье мы обсудили все, что необходимо знать для реализации базовой аналитики производственного уровня в вашем Flutter‑приложении:
Почему аналитика необходима для уверенных релизов и роста
Как продумать и правильно выбрать события для отслеживания
Простая архитектура для быстрой реализации аналитики
Масштабируемая типобезопасная архитектура для более крупных приложений и команд
Как отслеживать события из виджетов и контроллеров
Как интегрировать Firebase Analytics, не влияя на остальную логику приложения
Однако это лишь первый шаг к реализации аналитики в реальных приложениях.
Прежде чем публиковать ваше приложение, стоит учесть несколько важных моментов:
Отслеживание экранного вида: Используйте навигационный наблюдатель, чтобы автоматически фиксировать переходы между экранами.
Аналитика в разных режимах: Позвольте пользователям отключать отслеживание, если это необходимо (например, для соблюдения GDPR).
Идентификация пользователя: Привязывайте события к зарегистрированным пользователям, чтобы отслеживать их на разных устройствах и анализировать воронку конверсии.
Интеграция с Mixpanel или PostHog: Firebase является бесплатным решением, но такие инструменты, как Mixpanel, предлагают мощную фильтрацию и отчетность и гораздо более удобны для обеспечения конфиденциальности.
Хотите узнать, как встроить аналитику в Flutter‑приложение так, чтобы каждый экран и клик превращались в ценные продуктовые инсайты? Тогда приглашаем всех желающих на бесплатный открытый урок, который пройдет 20 мая в 20:00.
Немного практики в тему — попробуйте пройти вступительный тест по Flutter и получите обратную связь по своим знаниям.