18 de dez. de 2025·7 min de leitura

APNs vs FCM para notificações push no iOS e Android

APNs vs FCM para iOS e Android: ciclo de vida de tokens, limites de payload, expectativas de entrega e uma checklist prática para resolver pushes ausentes.

APNs vs FCM para notificações push no iOS e Android

O que você está comparando (e por que importa)

APNs (Apple Push Notification service) e FCM (Firebase Cloud Messaging) são os canais que movem uma mensagem do seu servidor até um telefone. Eles não decidem o que seu app faz com a mensagem, mas influenciam fortemente se ela chega, quão rápido chega e em que formato ela precisa estar.

Quando alguém diz que uma notificação push “funciona no Android, mas não no iOS” (ou o contrário), raramente é um único bug. iOS e Android lidam com trabalho em background, economia de energia, permissões e prioridade de mensagens de formas diferentes. A mesma mensagem pode ser atrasada, substituída por outra mais recente, mostrada sem som ou nunca exibida se o app não puder acordar para processá-la.

Esta comparação foca nas partes que causam as maiores surpresas no mundo real: como os tokens de dispositivo mudam com o tempo, qual o tamanho máximo de payload e como estruturá-lo, que tipo de entrega é razoável esperar e os motivos comuns pelos quais notificações parecem sumir.

Isto não cobre escolha de UI de provedores de push, estratégia de marketing ou construção de um pipeline completo de analytics. O objetivo aqui é confiabilidade e depuração mais rápida.

Alguns termos usados ao longo do texto:

  • Token: um endereço específico do dispositivo para o qual você envia, emitido por APNs ou FCM.
  • Topic: um endereço em grupo (usado principalmente com FCM) onde muitos dispositivos se inscrevem.
  • Channel: uma categoria de notificação no Android que controla som, importância e comportamento.
  • Collapse key: uma forma de substituir mensagens pendentes antigas por uma mais nova.
  • TTL (time to live): quanto tempo uma mensagem pode aguardar entrega antes de expirar.

Acertar esses básicos economiza horas de suposições quando um “push simples” se comporta de forma diferente entre iOS e Android.

Como APNs e FCM funcionam em alto nível

APNs e FCM são ambos intermediários entre seu servidor e o telefone do usuário. Seu app não consegue entregar de forma confiável uma notificação diretamente ao dispositivo via internet, então entrega essa tarefa à Apple (APNs) ou ao Google (FCM), que mantêm conexões confiáveis com seus dispositivos.

O fluxo geral é parecido: seu app obtém um token, seu backend envia uma mensagem ao serviço de push usando esse token, e o serviço roteia para o dispositivo.

APNs em termos simples

No iOS, o app se registra para notificações remotas e (geralmente) pede permissão ao usuário. A Apple então fornece um device token. Seu backend (frequentemente chamado de “provider”) envia uma requisição de push ao APNs que inclui esse token e seu payload. O APNs decide se pode entregar e repassa a notificação ao dispositivo.

Seu backend autentica no APNs, tipicamente usando autenticação baseada em token (uma chave de assinatura). Configurações antigas usam certificados.

FCM em termos simples

No Android, a instância do app se registra no FCM e recebe um registration token. Seu backend envia uma mensagem ao FCM, que roteia para o dispositivo correto. Dependendo do estado do app e do tipo de mensagem, o FCM pode exibir a notificação automaticamente ou entregar os dados ao app para tratamento.

Seu backend autentica no FCM usando credenciais de servidor (API key ou service account).

O que você controla: código do app, quando solicitar permissão, armazenamento de tokens, lógica do backend e o payload que envia. O que Apple e Google controlam: a rede de entrega, alcançabilidade, regras de throttling e muitas condições de última milha como políticas do sistema e economia de energia.

Ciclo de vida do token: como tokens são emitidos, renovados e invalidados

A maior diferença no dia a dia entre APNs e FCM é que tokens não são “definidos uma vez para sempre”. Trate-os como endereços que podem mudar sem aviso.

No iOS, o device token do APNs está ligado ao dispositivo, ao seu app e à sua configuração de desenvolvedor Apple. Ele pode mudar após reinstalação do app, restauração do dispositivo, certas atualizações do SO ou ao trocar ambientes de push (sandbox vs production) durante o desenvolvimento.

No Android, o registration token do FCM pode ser renovado quando o app é restaurado em um novo dispositivo, o usuário limpa os dados do app, o Google rotaciona o token ou o app é reinstalado. Seu app deve esperar eventos de refresh e enviar o token novo ao servidor prontamente.

Uma regra simples: sempre faça upsert dos tokens, nunca “inserir e esquecer”. Ao armazenar tokens, mantenha contexto suficiente para evitar duplicatas e alvos errados:

  • ID do usuário ou conta (se aplicável)
  • Bundle/package do app e ambiente
  • Plataforma (iOS/Android)
  • Valor do token e timestamp de último visto
  • Status de opt-in (permissão concedida/negada)

Deleções também importam. Geralmente você descobre que um token morreu a partir de erros de entrega, não de um sinal limpo de “uninstall”. Se o APNs retornar um erro como Unregistered (frequentemente com status 410), ou o FCM indicar NotRegistered/Unregistered, remova o token imediatamente para parar de tentar para sempre.

Uma maneira fácil de vazar atualizações privadas: um cliente faz logout e outro faz login no mesmo telefone. Se você não limpar ou remapear o token no logout, pode enviar notificações para a pessoa errada mesmo que a entrega “funcione”.

Restrições de payload e diferenças na estrutura da mensagem

A maior diferença prática entre APNs e FCM é o que você consegue colocar numa mensagem e como o telefone a trata ao chegar.

A maioria das equipes usa um conjunto pequeno de campos:

  • Texto de título e corpo
  • Contador de badge (iOS)
  • Som (default ou custom)
  • Dados customizados em chave-valor (por exemplo, order_id, status)

Limites de tamanho: mantenha o push pequeno

Ambos os serviços têm limites de tamanho de payload, e o limite inclui seus dados customizados. Quando você atinge o limite, a entrega pode falhar ou a mensagem pode não se comportar como esperado.

Um padrão confiável é enviar uma notificação curta mais um ID e então buscar detalhes no seu backend:

Exemplo: em vez de enviar um resumo completo do pedido, envie {"type":"order_update","order_id":"123"} e deixe o app chamar sua API para obter o status mais recente.

Data-only vs comportamento de notification

No Android, uma mensagem FCM com payload "notification" normalmente é exibida pelo sistema quando o app está em background. Uma mensagem somente com dados (data-only) é entregue ao código do app, mas pode ser atrasada ou bloqueada por limites de background e configurações de bateria.

No iOS, alerts (título/corpo) são diretos, mas atualizações em background são mais restritas. Um push de background não garante que seu código será executado imediatamente. Trate-o como um aviso para atualizar, não como um gatilho em tempo real.

Se você precisa de confiabilidade, mantenha o payload mínimo, inclua um identificador estável e projete seu app para reconciliar estado quando abrir ou retomar.

Expectativas de entrega e o que pode impedir uma notificação

Desenhe a lógica de envio de push visualmente
Use lógica visual para lidar com retries, escolhas de TTL e comportamento de colapso de forma clara.
Criar fluxo de trabalho

Tanto com APNs quanto com FCM, a entrega é best-effort. O provedor tentará entregar sua mensagem, mas não garante que o dispositivo vai mostrá-la.

A alcançabilidade é o primeiro limitador. Você envia uma notificação com um time-to-live (TTL) ou expiry. Se o dispositivo voltar online depois dessa janela, o push é descartado. Se o TTL for muito longo, o usuário pode ver um alerta antigo depois, o que parece um bug.

A prioridade afeta o timing, mas não é um upgrade gratuito. Alta prioridade pode ajudar mensagens sensíveis ao tempo a chegarem mais rápido, especialmente quando o dispositivo está dormindo. Abusar disso pode levar a throttling, consumo de bateria ou o SO tratar seu app como ruidoso.

Ambos os sistemas suportam colapso para que uma mensagem mais nova substitua uma mais antiga em vez de empilhar. APNs usa um collapse identifier, e FCM usa collapse key. Se você colapsar em algo como order_status, o usuário pode ver apenas o status mais recente, não cada etapa.

Mesmo quando o provedor entrega com sucesso, o telefone ainda pode impedir o usuário de ver:

  • Modos Não Perturbe ou Focus podem silenciar ou esconder alertas
  • Configurações de notificação do app podem estar desativadas ou em entrega silenciosa
  • Canais de notificação no Android podem estar desligados para uma categoria específica
  • Restrições de background ou economizadores de bateria podem atrasar a entrega
  • O SO pode suprimir repetições se seu app postar muitos alertas similares

Trate push como um transporte não confiável: mantenha estado importante no backend e faça o app atualizar o status quando for aberto, mesmo que uma notificação nunca apareça.

Permissões e configurações do dispositivo que afetam a entrega

Muitos “problemas de entrega” são na verdade questões de permissão e configurações.

No iOS, o primeiro prompt de permissão importa. Se o usuário tocar em “Don’t Allow”, notificações não aparecerão até que ele altere isso em Ajustes. Mesmo após permitir, ele pode desativar Tela Bloqueada, Central de Notificações, banners, sons ou badges. Modos Focus e Scheduled Summary também podem esconder ou atrasar alertas.

No Android, os requisitos dependem da versão do SO. Versões mais novas exigem permissão de notificação em tempo de execução, então uma atualização do app pode parar de mostrar notificações até o usuário aprovar novamente. Visibilidade também depende de canais de notificação. Se o canal estiver silenciado ou com baixa importância, pushes podem chegar mas nunca interromper.

Restrições de background também podem quebrar expectativas. Low Power Mode no iOS e otimizações de bateria no Android podem atrasar trabalho em background, cortar dados em background ou impedir o app de processar uma mensagem data-only.

Para confirmar o que está acontecendo, registre o que o dispositivo vê, não apenas o que seu backend enviou:

  • Logs in-app: “permission granted”, “token registered”, “notification received”, “notification displayed”
  • Indicadores do SO: estado das configurações de notificação (habilitado/mudo/importância do canal) e modo de bateria
  • Callbacks de push: se seu app recebeu a mensagem em foreground/background

Mesmo que seu backend seja construído em uma ferramenta no-code, o logging no cliente ainda é o que separa “mensagem não recebida” de “recebida mas suprimida”.

Passo a passo: como depurar notificações ausentes

Gere apps nativos para ambos
Envie apps nativos iOS e Android que funcionem corretamente com APNs e FCM.
Construir apps móveis

Quando um push some, trate isso como uma cadeia: token, provedor, payload e comportamento do app. Os sintomas podem ser iguais no iOS e no Android, então verifique os mesmos pontos nesta ordem.

  • Confirme que está enviando para um token atual. Compare o token armazenado no servidor com o token que o app reportou por último. Registre quando recebeu cada token.
  • Valide o payload antes de enviar. Mantenha-o dentro dos limites da plataforma, use campos obrigatórios e evite JSON malformado. Se enviar mensagens somente com dados, confirme que o app está preparado para processá-las.
  • Cheque credenciais e ambiente do provedor. Para APNs, confirme key/cert, team, bundle ID e se está mirando sandbox vs production. Para FCM, confirme as credenciais do projeto correto.

Depois, afine se é conteúdo da mensagem ou comportamento do dispositivo/app:

  • Envie uma notificação de teste mínima. Um payload minúsculo com título/corpo ajuda a confirmar que o transporte funciona.
  • Verifique handlers do app e comportamento em foreground. Muitas notificações “sumidas” são recebidas mas não mostradas. Alguns apps suprimem banners em foreground por design.
  • Mude apenas uma variável por vez. Tente outro dispositivo, outra versão do SO, Wi-Fi vs celular e outra conta de usuário. Se só uma conta falha, normalmente aponta para tokens obsoletos ou targeting no servidor.

Um padrão prático: se usuários iOS reportam faltas mas Android está ok, comece enviando um alerta mínimo no iOS. Se isso funcionar, foque na estrutura do payload e no tratamento do app. Se não funcionar, foque em tokens e credenciais/ambiente do APNs.

Erros comuns que causam falhas silenciosas

Use push como um gatilho
Envie pushes leves com IDs e depois busque detalhes da sua API quando o app abrir.
Construir API

A maioria dos problemas de push não são quedas de serviço. São pequenos desalinhamentos entre o que seu app espera e o que APNs ou FCM aceitarão, ou o que o telefone permitirá.

O mais comum é enviar para um token que não é mais válido. Tokens mudam após reinstall, restore ou refresh. Se seu servidor continuar usando o valor antigo, pushes não chegam a lugar nenhum.

Outro erro é tratar a entrega de push como garantida. Entrega best-effort significa que mensagens atrasadas ou faltantes são normais quando dispositivos estão offline ou sob regras de economia de energia. Para eventos importantes (atualizações de pedido, alertas de segurança), você precisa de um fallback no app, como buscar o status mais recente ao abrir.

Causas comuns de notificações perdidas:

  • Tokens iOS/Android obsoletos mantidos após reinstall/refresh
  • Exceder limites de payload (dados customizados demais, imagens grandes, strings longas)
  • Confiar em entrega em background para atualizações silenciosas e ser throttled pelas limitações do SO
  • Misturar ambientes iOS (desenvolvimento vs produção), fazendo token e endpoint APNs não coincidirem
  • Ignorar opt-out do usuário, Focus/Do Not Disturb, canais de notificação desativados (Android) ou permissões do app

Exemplo: um app de varejo envia um alerta “pedido enviado” com um grande blob JSON do histórico de rastreamento. A chamada de envio parece ok, mas o payload é rejeitado ou truncado, e o usuário não vê nada. Mantenha o push pequeno e coloque detalhes atrás de uma chamada de API.

Checklist rápido antes de culpar APNs ou FCM

Antes de supor que o provedor é o problema, faça uma verificação rápida:

  • Confirme que o token está correto para o usuário e dispositivo. Deve existir, ter sido atualizado recentemente e estar mapeado para a sessão certa.
  • Verifique se as credenciais do provedor são válidas agora. Cheque chaves/certs do APNs e credenciais do FCM que correspondam ao app/projeto certo.
  • Valide formato e tamanho do payload. Fique abaixo dos limites e use os campos corretos.
  • Defina TTL, prioridade e colapso intencionalmente. TTL curto pode expirar antes do telefone voltar online. Prioridade baixa pode atrasar a entrega. Colapso pode substituir mensagens anteriores.
  • Separe “ser aceito pelo servidor” de “ser exibido no dispositivo”. Compare logs do servidor (request/response/message ID) com logs do cliente (token usado, handler chamado).

Depois faça uma checagem rápida no dispositivo: notificações permitidas para o app, canal/categoria correta configurada (canais Android são um erro comum), Focus/Do Not Disturb, e restrições de background.

Exemplo: diagnosticando uma notificação de atualização de pedido ausente

Padronize seu runbook de push
Transforme sua checklist de resolução em workflows backend repetíveis que sua equipe confie.
Começar grátis

Um agente de suporte toca “Enviar atualização de pedido” para o Pedido #1842. Os logs do backend mostram “notificação enviada”, mas o cliente não vê nada no iPhone nem no Android.

Comece pelo backend. A maioria das notificações “sumidas” ou nunca são aceitas pelo serviço de push, ou são aceitas mas descartadas depois porque o dispositivo não pode (ou não vai) mostrá-las.

Verificações no backend primeiro

Procure por uma tentativa de envio única e rastreável (cada atualização de pedido deve produzir uma requisição de push). Então verifique:

  • O token usado é o mais recente armazenado para aquele usuário/dispositivo.
  • A resposta do provedor indica sucesso, e você salvou qualquer código de erro.
  • O payload segue regras da plataforma (limites de tamanho, campos necessários, JSON válido).
  • A autenticação está válida (key/cert do APNs e team/bundle IDs, ou credenciais FCM).
  • Você direcionou o ambiente iOS correto (sandbox vs production).

Se seus logs mostram uma rejeição como “unregistered/invalid token”, é um problema de ciclo de vida do token. Se o provedor aceita a mensagem mas nada chega, foque no tipo de payload e no comportamento do SO.

Verificações no aparelho

Agora valide se o telefone pode mostrar o alerta:

  • Notificações estão habilitadas para o app (e permitidas para Tela Bloqueada/Banners).
  • Focus/Do Not Disturb ou summaries não estão escondendo a notificação.
  • Modos de economia de bateria não estão restringindo trabalho em background (mais comum no Android).
  • O estado do app coincide com o tipo de mensagem (tratamento em foreground pode consumir alerts).

Um resultado comum: o token está ok, mas a mensagem é somente dados (Android) ou falta a configuração correta no iOS para tratar background, então o SO nunca exibe um alerta. A correção é enviar o tipo certo de payload para o que você quer (alerta visível vs atualização em background) e manter logs claros de atualizações de token e respostas do provedor.

Próximos passos: tornar o push mais confiável no seu produto

Notificações push parecem simples até que se tornam um recurso central. Confiabilidade vem das peças que você controla: higiene de tokens, disciplina de payload e um caminho de fallback.

Planeje para perdas. Push é ótimo para momentos "veja agora", mas não deve ser a única via para eventos críticos. Uma caixa de entrada no app ajuda usuários a se atualizarem depois, e e-mail ou SMS pode cobrir ações de alto valor como reset de senha ou problemas de pagamento.

Mantenha o payload enxuto. Trate o payload do push como um prompt, não como a mensagem completa. Envie um tipo de evento e um ID, e busque detalhes na sua API quando o app abrir ou quando receber uma atualização de background apropriada.

Escreva um runbook curto para sua equipe para que a depuração seja consistente: estado de opt-in, frescor do token, códigos de resposta do provedor, tamanho/formato do payload e ambiente/credenciais.

Se você está construindo com AppMaster (appmaster.io), pode ser conveniente centralizar armazenamento de tokens, logs de auditoria e lógica de gatilho de push em um backend, enquanto ainda entrega apps nativos iOS e Android que tratem APNs e FCM corretamente.

FAQ

Qual é a maneira mais simples de explicar APNs vs FCM?

APNs é o serviço de entrega da Apple para notificações push no iOS, e FCM é o serviço do Google para Android (e que também pode atingir iOS via APNs). Seu app continua decidindo o que fazer com a mensagem, mas esses serviços determinam como você autentica, como formatar o payload e qual comportamento de entrega esperar.

Os tokens de dispositivo ficam iguais para sempre?

Trate tokens como endereços que podem mudar. Armazene-os com detalhes de plataforma e ambiente, atualize sempre que o app reportar um novo valor e remova-os quando o provedor indicar que são inválidos. A regra prática é fazer upsert dos tokens e manter um carimbo de “último visto” para identificar registros obsoletos rapidamente.

O que geralmente faz um token de push do iOS ou Android mudar?

No iOS, tokens costumam mudar após reinstalação, restauração do dispositivo, algumas atualizações do SO ou quando você alterna entre sandbox e production durante o desenvolvimento. No Android, os tokens FCM podem ser renovados após reinstalação, quando o usuário limpa dados do app, quando o dispositivo é restaurado ou quando o Google rotaciona tokens. O app deve ouvir eventos de refresh e enviar o token novo ao backend imediatamente.

Como devo estruturar um payload de push para evitar problemas?

Mantenha o payload de push pequeno e trate-o como um prompt. Envie um título/resumo curto (se precisar de alerta visível) mais um identificador estável como order_id, e permita que o app busque os detalhes completos da sua API. Isso evita limites de payload, reduz edge cases estranhos e torna o comportamento mais consistente entre plataformas.

Qual é a diferença entre mensagens “notification” e “data-only”?

Um payload de "notification" destina-se a ser mostrado ao usuário, enquanto um payload somente com dados (data-only) é para o app processar. No Android, mensagens data-only podem ser atrasadas ou bloqueadas por limites de background e configurações de bateria, então não são gatilhos confiáveis para trabalho imediato. No iOS, pushes em background também não garantem que seu código será executado imediatamente; trate-os como um aviso para atualizar, não como um executor em tempo real.

As notificações push são garantidas para serem entregues e mostradas?

Não. A entrega é best-effort. Mesmo que APNs ou FCM aceitem sua requisição, o dispositivo pode estar offline, a mensagem pode expirar por TTL, o sistema pode limitar a entrega ou configurações do usuário podem suprimir o alerta. Projete seu app para que o estado crítico esteja correto quando o usuário abrir o app, mesmo que a notificação nunca seja exibida.

Qual é a maneira mais rápida de depurar uma notificação ausente?

Separe “enviado” de “exibido”. Confirme se o token está atualizado, envie um payload mínimo de teste com título/corpo e verifique se você está usando as credenciais APNs/FCM corretas e (no iOS) o ambiente certo. Se o provedor aceitar a mensagem, cheque configurações do telefone como Focus/Não Perturbe, permissões do app e canais de notificação no Android — a notificação pode ter sido recebida mas suprimida.

Por que notificações funcionam no Android mas não no iOS (ou o contrário)?

No iOS, muitos problemas vêm de permissão negada, modos Focus ou de apontar para o ambiente APNs errado (sandbox vs production). No Android, bloqueadores comuns são a permissão de notificação em tempo de execução nas versões mais novas, canais de notificação silenciados/baixa importância e otimizações agressivas de bateria que atrasam processamento em background. O mesmo envio do backend pode parecer ok enquanto o dispositivo impede silenciosamente que o usuário veja algo.

Como TTL e “collapse key” afetam o que os usuários veem?

TTL controla por quanto tempo o provedor deve tentar enquanto o dispositivo está offline, e configurações de colapso determinam se mensagens mais novas substituem as pendentes. Um TTL curto pode fazer notificações desaparecerem se o telefone ficar offline por um tempo, e chaves de colapso podem fazer com que só a atualização mais recente apareça. Defina esses valores intencionalmente com base na experiência desejada, não deixe como defaults sem revisão.

Como o AppMaster pode me ajudar a montar um setup confiável de push?

Mantenha armazenamento de tokens, regras de segmentação e logs de envio juntos para traçar cada tentativa de envio de ponta a ponta. AppMaster (appmaster.io) pode ajudar ao centralizar tabelas de tokens, auditoria e lógica de gatilho de push em um backend, enquanto seus apps nativos iOS e Android lidam corretamente com APNs e FCM. O essencial é registrar atualizações de token, respostas do provedor e recibo no cliente para identificar se a falha é do servidor, provedor ou do dispositivo.

Fácil de começar
Criar algo espantoso

Experimente o AppMaster com plano gratuito.
Quando estiver pronto, você poderá escolher a assinatura adequada.

Comece