Erros do Firebase App Check: corrija 403, “App attestation failed” e tokens inválidos
Os erros do App Check acontecem em uma de duas etapas: quando o app recebe um token do provedor de atestado (Play Integrity, App Attest, reCAPTCHA) ou quando um serviço do Firebase confere esse token. Se a primeira etapa falha, a segunda também falha. Por isso, não pare no erro do serviço: procure primeiro o erro da troca de tokens e corrija os valores registrados da sua plataforma. Emuladores, simuladores e localhost, por natureza, não passam no atestado e usam um token de depuração.
Em resumo
- Primeiro, encontre a etapa que falhou. Se a troca de tokens terminou em 403, o problema está na configuração do provedor; se só o serviço recusa as solicitações, sem erro na troca, o token está ausente ou é inválido. Diferenciar pela mensagem
- No desenvolvimento, use um token de depuração. Emuladores, simuladores, localhost e builds com assinatura de depuração não passam no atestado real. Como registrar
- Cada plataforma tem valores que precisam coincidir. No Android, o SHA-256 do certificado de assinatura; na Apple, o Team ID e o ambiente production do App Attest; na web, os domínios da chave do reCAPTCHA. Causas por plataforma
- Desde 2 de novembro de 2026, o App Check é aplicado automaticamente ao AI Logic. Só dá para adiar até 21 de janeiro de 2027. O que fazer
Encontrar pela mensagem a etapa que falhou
| Mensagem | Etapa que falhou |
|---|---|
Android: Error returned from API. code: 403 body: App attestation failed. | Obtenção do token. O servidor do App Check não aceitou o resultado da Play Integrity. |
Apple: The server responded with an error … HTTP status code: 403 | Obtenção do token. O resultado do App Attest ou do DeviceCheck não foi aceito. |
Web: HTTP status: 403. (appCheck/fetch-status-error), seguido de appCheck/throttled | Obtenção do token. O resultado do reCAPTCHA não foi aceito, e o SDK não tenta de novo por 24 horas. |
Cloud Storage: Firebase App Check token is invalid. (no SDK da web, storage/unauthorized-app) | Uso do token. O token está ausente ou é inválido. |
Funções chamáveis (callable): functions/unauthenticated | Uso do token. Uma função com enforceAppCheck: true o recusou. Um token do Auth inválido dá o mesmo código, então a diferença está na linha AppCheck token was rejected no log da função. |
Realtime Database: Provided AppCheck credentials for the app named ... are invalid | Uso do token. O token é inválido. |
Firebase AI Logic: 403 PERMISSION_DENIED: ... you must enforce Firebase App Check. | Uso do token. Veja a seção AI Logic. |
Se o app não consegue o token, as solicitações ao serviço não levam um token válido (o SDK da web envia um token fictício no lugar). Por isso, mesmo que o erro apareça do lado do serviço, confira primeiro se o log também mostra um erro ao obter o token. Depois de uma falha, o SDK adia as novas tentativas: na web, 24 horas depois de um 403 ou 404; no Android e na Apple, 24 horas depois de um 400 ou 404; e, nos outros erros, até 4 horas. Esse estado fica só na memória, então, depois de corrigir a configuração, reinicie o app ou recarregue a página antes de conferir.
Token de depuração durante o desenvolvimento
Emuladores e simuladores não são reconhecidos como dispositivos válidos, e builds de depuração que não estão no Google Play não passam na Play Integrity. Por regra, chaves do reCAPTCHA não incluem localhost. Nesses ambientes, ative o provedor de depuração e registre no console o token que aparece no log.
- Ative o provedor de depuração só nos builds de desenvolvimento.
// Android (Kotlin): com.google.firebase:firebase-appcheck-debug Firebase.appCheck.installAppCheckProviderFactory( if (BuildConfig.DEBUG) DebugAppCheckProviderFactory.getInstance() else PlayIntegrityAppCheckProviderFactory.getInstance(), ) // iOS (Swift): before FirebaseApp.configure() #if DEBUG AppCheck.setAppCheckProviderFactory(AppCheckDebugProviderFactory()) #endif // Web: before initializeAppCheck(), in development builds only self.FIREBASE_APPCHECK_DEBUG_TOKEN = true; // Flutter (firebase_app_check 0.5+) await FirebaseAppCheck.instance.activate( providerAndroid: kDebugMode ? const AndroidDebugProvider() : const AndroidPlayIntegrityProvider(), providerApple: kDebugMode ? const AppleDebugProvider() : const AppleAppAttestWithDeviceCheckFallbackProvider(), ); - Execute o app e procure o token de depuração no log. Os SDKs atuais o imprimem no formato
Firebase App Check debug token: <UUID>(no Android, no logcat; na Apple, no console do Xcode; na web, no console do navegador). - Registre o token. No console do Firebase, abra a guia Apps do App Check e, no menu ⋮ do app, escolha Gerenciar tokens de depuração (Manage debug tokens). É possível registrar até 20 por app.
- Os tokens mudam. Um token novo é gerado no Android quando você limpa os dados do app ou o reinstala; na Apple, quando o reinstala; e na web, quando usa outro perfil do navegador ou limpa os dados do site. O token novo precisa ser registrado de novo.
- Em CI, passe um token já registrado. Na web, use a string do token em
self.FIREBASE_APPCHECK_DEBUG_TOKEN; no Android, o argumento de instrumentaçãofirebaseAppCheckDebugSecret; na Apple, a variável de ambiente do esquemaAppCheckDebugToken; e no Flutter, o parâmetrodebugToken. - Trate o token como uma senha. Não o envie para o repositório e mantenha o provedor de depuração e o token fora dos builds de produção.
Causas por plataforma
Android (Play Integrity)
| Sintoma | Causa | Solução |
|---|---|---|
| Só falha em emuladores ou builds de depuração | Emuladores não são dispositivos válidos, e o Google Play não conhece a assinatura de depuração. | Token de depuração |
| O app baixado do Play falha | Você registrou o SHA-256 da chave de upload. Com a Assinatura de apps do Google Play, o Google assina o app de novo com a chave de assinatura do app. | Registrar no App Check o SHA-256 do certificado da chave de assinatura do app que aparece na página Gerenciar a Assinatura de apps do Google Play (Manage Play app signing) do Play Console |
| Um app distribuído fora do Play falha | Por padrão, só passam as versões do app que o Google Play reconhece (PLAY_RECOGNIZED). | Nas configurações da Play Integrity do App Check, mudar PLAY_RECOGNIZED para Não obrigatório (Not required) e subir a integridade mínima do dispositivo para Integridade do dispositivo (Device integrity) |
Falha conforme os usuários aumentam (TOO_MANY_REQUESTS, -8) | Projetos do Cloud não vinculados no Play Console ficam limitados a 10.000 solicitações da Play Integrity por dia. | Na seção API Play Integrity do Play Console, vincular o projeto do Firebase com Vincular projeto do Cloud (Link Cloud project) e, se precisar, pedir um aumento de cota. Só é possível vincular apps que estão no Google Play. |
Apple (App Attest, DeviceCheck)
| Sintoma | Causa | Solução |
|---|---|---|
| Falha no simulador | O simulador não é um dispositivo válido. | Token de depuração |
| Só falham os builds instalados pelo Xcode | Adicionar a capability App Attest define o ambiente como development, e o App Check não aceita os resultados desse ambiente. Builds do TestFlight e da App Store sempre usam production. | Definir App Attest Environment como production no arquivo de entitlements |
| Falha em todos os dispositivos | O Team ID registrado no Firebase não é o do app. | Informar o Team ID correto do app Apple nas configurações do projeto do Firebase |
| Falha no Mac ou em extensões de app | O App Attest não é compatível com esses ambientes. | Adicionar o DeviceCheck como provedor alternativo. Para o DeviceCheck, registrar no App Check a chave (.p8) criada no site para desenvolvedores da Apple e o ID dela |
| Flutter: o provedor escolhido não é usado em dispositivos reais | Chamar FirebaseApp.configure() antes no AppDelegate faz o providerApple ser ignorado. | Remover o configure() do AppDelegate e usar só o Firebase.initializeApp() no Dart |
Web (reCAPTCHA)
| Sintoma | Causa | Solução |
|---|---|---|
| Só falha no site implantado | O domínio não está na lista de domínios da chave do reCAPTCHA. | Adicionar o domínio nas configurações da chave. Pode levar até 30 minutos para entrar em vigor |
| Falha no localhost | Chaves de produção não incluem localhost. | Token de depuração |
| Falha depois de trocar de chave | A classe do provedor e o valor registrado no Firebase não combinam. | Chave Enterprise: ReCaptchaEnterpriseProvider no código e a chave do site no Firebase. Chave v3: ReCaptchaV3Provider no código e a chave secreta no Firebase |
| Continua falhando depois da correção | Depois de um 403 ou 404, o SDK não tenta a troca de tokens de novo por 24 horas. | Recarregar a página. Esse estado fica só na memória. |
AI Logic: aplicação automática desde 2 de novembro de 2026
Desde 2 de novembro de 2026, o Firebase aplica automaticamente o App Check ao Firebase AI Logic nos projetos que não o aplicavam. Solicitações sem um token válido são bloqueadas, e o mesmo vale para versões do app publicadas sem App Check. Dois erros do AI Logic mencionam o App Check.
403 PERMISSION_DENIED: To access this model, you must enforce
Firebase App Check.
403 PERMISSION_DENIED: Firebase AI Logic has been deactivated in this
project. To resume using Firebase AI Logic, you must enforce Firebase
App Check.- O primeiro aparece quando um modelo que costuma sofrer abuso é chamado sem um token válido do App Check. Configure e aplique o App Check. Durante o desenvolvimento, use o provedor de depuração.
- O segundo aparece quando o projeto foi considerado inativo e não aplica o App Check. Se você já aplica e o erro aparece mesmo assim, confira a proteção contra repetição (replay protection): quando ela está ativada, inclusive no modo Monitor only, só valem tokens de uso limitado (limited-use tokens).
Se versões sem App Check ainda estão nas mãos dos usuários, é possível adiar a aplicação. Basta mudar a data do seletor Aplicar (Enforces) na linha do Firebase AI Logic da guia APIs do App Check; 21 de janeiro de 2027 é a última data possível. Se a linha já mostra Aplicado (Enforced), para suspender a aplicação é preciso mudar a data e, depois, em Configurar (Set up) dessa linha, passar a Proteção de referência (Baseline protection) para Unenforced (monitoring only) e a proteção contra repetição para Disabled. O Google não recomenda isso, então publique antes dessa data uma versão com App Check.
Antes de aplicar a outros serviços
- Veja as métricas primeiro. A guia APIs do App Check divide as solicitações de cada serviço em verificadas (Verified), de cliente desatualizado (Outdated client, sem token), de origem desconhecida (Unknown origin) e inválidas (Invalid). Com a aplicação ativada, só passam as solicitações verificadas, então aplique quando quase todas as solicitações recentes forem verificadas.
- Versões antigas do app são bloqueadas. As versões sem o SDK do App Check têm as solicitações recusadas assim que você aplica o App Check.
- Pode levar até 15 minutos para entrar em vigor. Não tire conclusões logo depois de ativar a aplicação.
- No Cloud Functions, só as funções chamáveis podem ter o App Check aplicado. É preciso adicionar
enforceAppCheck: truee implantar de novo para valer. FunçõesonRequestficam fora da aplicação do App Check, então verifique o token você mesmo com o Admin SDK.
Fontes
- Visão geral do App Check, ativar a aplicação, monitorar métricas, limite de tokens de depuração (REST)
- Provedor da Play Integrity, cota da Play Integrity, provedor de depuração para Android
- Provedor do App Attest, provedor do DeviceCheck, provedor de depuração para Apple, ambiente do App Attest (Apple), onde o App Attest pode ser usado (Apple)
- Provedor do reCAPTCHA Enterprise, provedor do reCAPTCHA v3, criar uma chave do reCAPTCHA, provedor de depuração para a web
- Provedor de depuração para Flutter,
activate()dofirebase_app_check - App Check para o AI Logic, códigos de erro do AI Logic, App Check para o Cloud Functions, verificar tokens no seu próprio back-end
- Código-fonte dos SDKs: limite de novas tentativas na web, token fictício na web, recusa no Storage, mensagem de erro no Android, novas tentativas no Android, novas tentativas na Apple, recusa nas funções chamáveis
