Flutter

SDK oficial pushhub_flutter sobre firebase_messaging, o integración por REST.

El SDK oficial pushhub_flutter se apoya en firebase_messaging, y agrega lo que ese plugin no hace:

  • registro del dispositivo, con cola sin conexión;
  • canal de Android;
  • notificaciones con la app abierta en Android, con imagen y botones;
  • aperturas y clics reportados, incluido el botón tocado en iOS;
  • usuarios, tags y topics.

Con firebase_messaging el token es de FCM en ambas plataformas. Necesitas:

Instalación

dependencies:
  firebase_core: ^5.1.0
  pushhub_flutter:
    path: ../pushhub_flutter      # mientras el paquete no esté en pub.dev
flutterfire configure

pushhub_flutter ya incluye firebase_messaging, flutter_local_notifications, http y shared_preferences.

  • Android: flutter_local_notifications requiere core library desugaring en android/app/build.gradle.kts:

    android {
        compileOptions { isCoreLibraryDesugaringEnabled = true }
    }
    dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") }
  • iOS: activa Push Notifications y Background Modes > Remote notifications en Xcode.

Uso

import 'package:firebase_core/firebase_core.dart';
import 'package:pushhub_flutter/pushhub_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  await PushHub.instance.init(const PushHubOptions(
    appKey: 'pk_live_TU_LLAVE_PUBLICA',          // solo la llave PUBLICA
    androidChannel: PushHubAndroidChannel(id: 'general', name: 'Avisos generales'),
  ));
  PushHub.instance.onNotificationOpened((n) {
    // n.deepLink, n.actionId (botón tocado), n.data (tus datos)
    if (n.deepLink != null) router.go(Uri.parse(n.deepLink!).path);
  });
  runApp(const MiApp());
}

// Pide el permiso cuando el usuario entienda para qué (no al abrir la app)
final estado = await PushHub.instance.requestPermission();   // granted, denied, ...

PushHub.instance.identify('cliente-123');     // al iniciar sesión
PushHub.instance.setTags({'plan': 'gold', 'ciudad': 'SDQ'});
PushHub.instance.subscribe('ofertas');
PushHub.instance.logout();                    // al cerrar sesión

Registra onNotificationOpened al arrancar: si la app se abrió desde una notificación, el SDK guarda esa apertura y la entrega en cuanto te suscribes.

Las llamadas (identify, setTags, subscribe) no esperan red: se guardan en una cola persistente. Se envían cuando hay token y conexión, y se reintentan al volver a la app.

Opciones de PushHubOptions

Opción Por defecto Descripción
appKey — Llave pública pk_live_… o pk_test_…. El SDK rechaza llaves secretas.
appId — Solo si la llave no está limitada a una app.
autoRegister false Pedir el permiso al iniciar.
foregroundDisplay true Mostrar las notificaciones con la app abierta.
androidChannel — Canal que el SDK crea; debe coincidir con el canal por defecto de la app en PushHub.
iosNotificationServiceExtension false La app incluye la extensión (ver abajo); habilita imágenes y botones en iOS.
apiUrl https://api.pushhub.daertec.com Solo para pruebas.
debug false Logs en la consola.

Dispositivo de prueba

En Dispositivos, el panel muestra un código de emparejamiento de 6 dígitos; en la app:

await PushHub.instance.pairTestDevice('483920');

Imágenes y botones en iOS

  1. En Xcode (ios/Runner.xcworkspace): File > New > Target > Notification Service Extension.
  2. Reemplaza el NotificationService.swift generado por el del paquete: ios/NotificationService/NotificationService.swift.
  3. Inicia el SDK con iosNotificationServiceExtension: true.

En Android, la imagen se muestra sin pasos extra. Los botones aparecen cuando la notificación llega con la app abierta (el SDK la muestra con flutter_local_notifications).

Installation ID de Firebase

Si activas el modo Installation ID de Firebase en la app, el SDK lo detecta y registra el FID en lugar del token de registro, sin cambios en tu código. Ver Installation ID de Firebase.

Lo que el SDK reporta

Evento Cuándo
received La notificación llega con la app abierta.
opened El usuario toca la notificación.
clicked El usuario toca un botón (incluye actionId).
permission_granted / permission_denied Cambia el permiso.

Sin SDK (REST)

Registra el token de FCM tú mismo con POST /v1/devices:

final token = await FirebaseMessaging.instance.getToken();
await http.post(
  Uri.parse('https://api.pushhub.daertec.com/v1/devices'),
  headers: {'Authorization': 'Bearer pk_live_TU_LLAVE_PUBLICA', 'Content-Type': 'application/json'},
  body: jsonEncode({'token': token, 'platform': Platform.isIOS ? 'ios' : 'android', 'provider': 'fcm', 'framework': 'flutter'}),
);

El id del envío llega en data['_phid'] y el enlace en data['deepLink']. Repórtalo a /v1/events al abrir.