PD Документация ← На главную

Flutter SDK

Пакет pushdata_flutter регистрирует устройство в PushData по нативному токену (FCM на Android, APNs на iOS), обновляет его, снимает при выходе и отмечает доставку, открытие и клик. Токены берёт через firebase_messaging. Работает только с публичным ключом приложения (pk_…), который можно хранить в приложении; отправки и контакты — с вашего сервера, секретным ключом.

Пакет публикуется. Пока pushdata_flutter не появился на pub.dev, подключите каталог sdk/flutter из репозитория PushData как path-зависимость: pushdata_flutter: { path: ../pushdata/sdk/flutter }. API и шаги руководства те же.

Требования: Flutter 3.19+, Dart 3.3+, проект Firebase; для iOS — аккаунт Apple Developer и физическое устройство (APNs не доставляет в симулятор).

1. Ключи приложения

В дашборде откройте Приложения → ваше приложение → Настройки: понадобятся ID приложения и публичный ключ pk_… (раздел «API-ключи»). Секретный ключ pd_… в приложение не попадает.

2. Провайдеры в PushData

  • Android → FCM. В Firebase Console создайте проект и Android-приложение с вашим package name; Project settings → Service accounts → Generate new private key. В дашборде Приложения → ваше приложение → Провайдеры Push → FCM: Project ID + JSON сервисного аккаунта.
  • iOS → APNs. В Apple Developer → Keys создайте ключ с APNs, скачайте .p8, запомните Key ID и Team ID. В дашборде Провайдеры Push → APNs: .p8, Key ID, Team ID, Bundle ID. PushData отправляет на iOS напрямую через APNs — SDK регистрирует токен APNs, а не токен FCM.

3. Firebase в проекте

bash
dart pub global activate flutterfire_cli
flutterfire configure        # создаёт lib/firebase_options.dart, кладёт google-services.json и GoogleService-Info.plist

iOS: в Xcode (ios/Runner.xcworkspace) Signing & Capabilities → + Capability → Push Notifications и Background Modes → Remote notifications. Android: flutterfire configure подключает плагин google-services; для Android 13+ SDK запрашивает разрешение на уведомления сам.

4. Установка пакета

yaml
dependencies:
  pushdata_flutter: ^0.1.0
  firebase_core: ^3.0.0
  firebase_messaging: ^15.0.0

5. Инициализация и регистрация

dart
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:pushdata_flutter/pushdata_flutter.dart';
import 'firebase_options.dart';

final pushData = PushDataFirebase(
  PushDataClient(
    appId: 'APP_ID',        // Приложения → Настройки
    publicKey: 'pk_…',      // Приложения → Настройки → API-ключи (публичный)
    // При включённой проверке идентичности — HMAC id пользователя с вашего сервера (шаг 8):
    // identityHashProvider: (userId) => backend.identityHash(userId),
  ),
);

@pragma('vm:entry-point')
Future<void> onBackgroundMessage(RemoteMessage message) async {
  // фоновый изолят для data-only сообщений; обычные уведомления показывает ОС
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
  runApp(const MyApp());
}

// После входа пользователя (или при старте — для анонимного устройства):
// разрешение, токен, POST /api/v1/public/devices, подписка на смену токена.
final registration = await pushData.start(userId: 'user-123', tags: ['news']);

start возвращает null, если пользователь запретил уведомления или токена ещё нет (на iOS SDK несколько секунд ждёт токен APNs). Окружение APNs SDK определяет сам: sandbox в debug-сборке, production в release; переопределить — start(apnsEnvironment: ApnsEnvironment.production).

6. Выход пользователя

dart
await pushData.stop();   // DELETE /api/v1/public/devices, отписка от событий

Один токен — одно устройство: start под другим userId переводит устройство новому пользователю.

7. События

В data каждого push PushData кладёт pushdata_notification_id и pushdata_device_id. PushDataFirebase отмечает delivered для сообщений, полученных в foreground (FirebaseMessaging.onMessage), и opened для тапа, который открыл приложение (onMessageOpenedApp, getInitialMessage). Клик по действию внутри уведомления — pushData.reportClicked(message). Показ уведомления в foreground (flutter_local_notifications) и переходы по ссылкам остаются вашим кодом.

Без firebase_messaging (свой источник токена) используйте PushDataClient напрямую: registerDevice(token:, platform:, userId:), unregisterDevice(token), track(event, notificationId:, deviceId:), PushDataClient.idsOf(data).

8. Проверка идентичности

При включённой Приложения → Настройки → Проверка идентичности регистрация с userId должна нести заголовок X-Identity-Hash — hex HMAC-SHA256 от id пользователя на секрете идентичности приложения. Секрет не покидает ваш сервер: сделайте авторизованный эндпоинт, который возвращает хэш, и передайте identityHashProvider в PushDataClient. Без него PushData ответит 401 identity_unverified. Анонимным устройствам хэш не нужен.

9. Проверка

  1. flutter run на устройстве, разрешите уведомления.
  2. Приложения → ваше приложение → Устройства: появилась строка с платформой и вашим user_id.
  3. Отправить уведомление → цель «пользователь» или «устройство» → push приходит; в карточке уведомления растут delivered и opened.
СимптомПроверьте
start вернул nullразрешение выдано; на iOS — capability Push Notifications, физическое устройство
401 unauthorizedpublicKey — ключ pk_ именно этого приложения
401 identity_unverifiedпроверка идентичности включена — задайте identityHashProvider или регистрируйте анонимно
iOS: push отправлен, ничего не пришлоKey ID / Team ID / Bundle ID у провайдера APNs; sandbox для debug, production для TestFlight; устройство ACTIVE
Android: push отправлен, ничего не пришлоJSON сервисного аккаунта у провайдера FCM от того же проекта; google-services.json в android/app

Ошибки SDK — PushDataException(status, code, message) с кодом сервиса (unauthorized, identity_unverified, validation_error, not_found, rate_limited).