Skip to main content

push_service_client 1.1.0 copy "push_service_client: ^1.1.0" to clipboard
push_service_client: ^1.1.0 copied to clipboard

Cliente Flutter para o Push Service — regista devices sozinho, recebe push notifications (FCM/APNs) e exibe mensagens in-app.

push_service_client #

Cliente Flutter para o Push Service — plataforma de push notifications. O pacote trata de tudo: inicializa o Firebase, pede permissões, obtém o token FCM/APNs, captura sozinho os dados do device (modelo, versões de app/SO, idioma, fuso horário), regista-o no serviço e liga os listeners para receber notificações.

O developer não precisa de saber qual é o token correto nem de embutir segredos na app. Só precisa do App ID público e de guardar o subscriptionId devolvido — é esse o id que o backend dele usa para enviar pushes.

Funcionalidades #

  • initialize() — faz tudo: Firebase + permissões + token + captura automática + registo + listeners
  • Captura automática: modelo, versão do SO, versão da app, idioma e fuso horário (IANA)
  • subscriptionId (UUID estável) — o identificador público para enviar pushes
  • Associar o device ao utilizador (setExternalId/clearExternalId) — login/logout
  • Subscribe / Unsubscribe / trackActivity — endpoints públicos, sem token
  • Envio de pushes — para devices: concretos ou segmentos (requer REST key)
  • Re-registo automático quando o token FCM é atualizado
  • Handlers de notificação — callbacks para push aberto/recebido
  • Mensagens in-app — busca automática no arranque da sessão, gatilhos (abrir app, duração de sessão, desde a última mensagem, personalizados), frequência e métricas (impressões/cliques/dispensas)

Instalação #

O pacote está publicado no pub.dev.

1. Adiciona o pacote #

No pubspec.yaml do teu projeto:

dependencies:
  push_service_client: ^1.1.0

Depois corre:

flutter pub get

2. Configura o Firebase #

O pacote usa firebase_core e firebase_messaging (já incluídos como dependências).

  • Android: adiciona o ficheiro google-services.json (da consola Firebase) em android/app/ e o plugin com.google.gms.google-services no android/build.gradle.
  • iOS: adiciona o ficheiro GoogleService-Info.plist em ios/Runner/.

Consulta o guia oficial do Firebase Flutter para os passos detalhados.

Utilização #

1. Configura #

Obtém o App ID público da app no painel do Push Service (Aplicações → API → App ID). É um UUID não secreto — pode ir dentro da app. O servidor (https://push.michelmelo.pt) está fixo no pacote.

final push = PushService(
  appId: 'uuid-publico-da-tua-app',   // NÃO é um token — é público
);

2. Inicializa (faz tudo) #

No main() (antes do runApp) ou no initState do widget raiz:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final push = PushService(appId: 'uuid-publico-da-tua-app');

  final device = await push.initialize(
    externalId: 'user-42',            // opcional — id do user na tua app
    tags: {'tier': 'vip'},            // opcional
    onOpened: (notification) {
      // utilizador tocou na notificação
      final url = notification.data['url'];
    },
    onReceived: (notification) {
      // notificação chegou com a app em primeiro plano
    },
  );

  // ⬇ IMPORTANTE — guarda no teu backend:
  // device.subscriptionId é o id estável deste device. É o que o teu servidor
  // envia na REST API para lhe mandar pushes. Nunca uses o token FCM/APNs.
  await meuBackend.guardarSubscriptionId(device.subscriptionId);

  runApp(MyApp(push: push));
}

O initialize:

  1. Inicializa o Firebase.
  2. Pede permissão de notificações.
  3. Obtém o token FCM/APNs.
  4. Captura sozinho: modelo, versão do SO, versão da app, idioma e fuso horário.
  5. Regista o device no Push Service (endpoint público).
  6. Liga os listeners (foreground, background, aberta, token atualizado).

Quando o token FCM for atualizado, o pacote re-regista automaticamente o device (o subscriptionId mantém-se o mesmo).

3. O ID do device — o que guardar #

Quando o device se regista (initialize ou registerDevice), o servidor devolve um subscriptionId (UUID público e estável). É este o ID que deves guardar no teu backend — é ele que identifica o device para envios futuros.

Nunca uses o playerId (token FCM/APNs) como referência: é apenas o token de envio e não serve como destino. E não uses o id numérico interno da resposta.

O subscriptionId mantém-se estável mesmo que o token FCM seja atualizado, ou se o device voltar a registar-se — o servidor reutiliza a linha existente (faz restore do registo anterior), preservando o mesmo subscriptionId.

4. Liga o device ao utilizador (login) #

Chama setExternalId depois do login/registo na tua app, com o ID do utilizador. O servidor associa o device à conta.

await push.setExternalId('user-42');   // após o login
await push.clearExternalId();          // após o logout

O externalId é o conceito de "utilizador" do Push Service: associa o device a uma identidade da tua app. Não há um id separado de utilizador — o targeting por "um utilizador" passa sempre por obter o(s) subscriptionId do device associado àquele externalId (ver secção 6).

5. Enviar pushes — do teu backend (REST API) #

O envio é feito pelo teu servidor, com um token REST (secreto) criado no painel:

curl -X POST https://push.michelmelo.pt/api/v1/apps/{slug}/pushes \
  -H "Authorization: Bearer {REST_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Olá!",
    "body": "Mensagem",
    "devices": ["subscription-id-guardado-no-passo-2"]
  }'

O servidor resolve o token FCM/APNs real a partir do subscriptionId e entrega. Também podes enviar por segment (plataforma, país, idioma, tags) — mas devices e segment são mutuamente exclusivos.

6. Enviar um push de um utilizador para outro #

Para enviar uma notificação a um utilizador específico, resolves o device desse utilizador para o seu subscriptionId e passas esse valor em devices. O teu backend tem de manter a associação externalId (teu id de user) → subscriptionId.

// A app regista-se e guarda a associação no teu backend:
final device = await push.initialize(externalId: 'user-42');
await meuBackend.guardarAssociacao('user-42', device.subscriptionId);

// Mais tarde, do teu servidor, para enviar do user A ao user B:
//  1. consulta o subscriptionId do teu user B por externalId
//  2. envia o push com devices: [subscriptionIdDoUserB]
curl -X POST https://push.michelmelo.pt/api/v1/apps/{slug}/pushes \
  -H "Authorization: Bearer {REST_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Nova mensagem",
    "body": "O utilizador A enviou-te algo",
    "devices": ["subscription-id-do-user-B"]
  }'

Resumindo o fluxo "user A → user B":

  1. Cada utilizador, ao entrar na app, regista-se (initialize) e o teu backend guarda externalId → subscriptionId.
  2. Quando o user A quer enviar ao user B, o teu servidor consulta o subscriptionId do user B (pela associação guardada no passo 1).
  3. Faz POST /pushes com devices: [<subscriptionId do user B>].
  4. O Push Service resolve o token real e entrega a notificação ao device do user B.

Não existe um endpoint "enviar por externalId" — o destino é sempre o subscriptionId do device.

7. (Opcional) Enviar a partir da app #

Se quiseres que a app consiga enviar pushes diretamente, passa também o token REST (atenção: token secreto numa app móvel é um risco — para testes apenas):

final push = PushService(
  appId: 'uuid-publico-da-tua-app',
  apiToken: 'REST_KEY_OPCIONAL',   // só se a app for enviar pushes
);
await push.sendPush(
  title: 'Olá!',
  body: 'Mensagem',
  devices: ['subscription-id-1', 'subscription-id-2'],  // OU segment
);

8. Desativa notificações no device #

await push.unsubscribe();   // deixa de receber pushes
await push.subscribe();     // volta a receber

9. Mensagens in-app #

Além de pushes, o SDK exibe mensagens in-app: no arranque de cada sessão busca as mensagens elegíveis para o device e mostra-as quando os gatilhos forem cumpridos. Não precisas de fazer nada — o initialize já o faz.

Para o SDK mostrar a mensagem sozinho, passa um navigatorKey:

final navigatorKey = GlobalKey<NavigatorState>();

final push = PushService(appId: 'uuid-publico-da-tua-app');

await push.initialize(
  navigatorKey: navigatorKey,
  onInAppMessageAction: (message, button) {
    // ações url / deep_link / push_permission (o "close" é tratado pelo SDK)
    if (button.action == 'url') abrirUrl(button.value!);
  },
);

// No teu MaterialApp:
MaterialApp(navigatorKey: navigatorKey, home: MyHome());

Sem navigatorKey, o SDK não desenha nada: chama onInAppMessage e é a tua app que renderiza (podes usar o widget InAppMessageView já incluído no pacote).

Os gatilhos são configurados no painel (abrir a app, duração da sessão, desde a última mensagem). Para gatilhos personalizados (custom), usa:

push.addTrigger('nivel', '3');   // cumpre o gatilho "nivel = 3"
push.removeTrigger('nivel');
push.clearTriggers();
push.checkInAppMessages();       // reavalia já os gatilhos

As impressões, cliques e dispensas são reportados automaticamente ao servidor (servem os relatórios e o controlo de frequência). Se renderizares a mensagem à tua maneira, reporta com:

push.reportInAppEvent(message.id, 'impression');
push.reportInAppEvent(message.id, 'click', buttonId: 'b1');
push.reportInAppEvent(message.id, 'dismiss');

Tratamento de erros #

Todas as chamadas lançam PushServiceException em caso de erro:

try {
  await push.initialize();
} on PushServiceException catch (e) {
  print('${e.statusCode}: ${e.message}');
}

Exemplo completo #

Vê a app de exemplo em example/.

Documentação da API #

A API v1 do Push Service está documentada em https://push.michelmelo.pt/docs.

0
likes
150
points
56
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Cliente Flutter para o Push Service — regista devices sozinho, recebe push notifications (FCM/APNs) e exibe mensagens in-app.

Homepage

License

MIT (license)

Dependencies

device_info_plus, firebase_core, firebase_messaging, flutter, flutter_timezone, http, package_info_plus

More

Packages that depend on push_service_client