Personalizar relatórios de erros do Firebase Crashlytics

Este guia descreve como personalizar os relatórios de erros usando as APIs do Crashlytics. Por padrão, o Crashlytics coleta automaticamente relatórios de erros nativos da plataforma para todos os usuários do seu app. Também é possível desativar os relatórios de falhas automáticos e ativar os relatórios de permissão para os usuários. O Crashlytics oferece cinco mecanismos de geração de registros prontos para uso: chaves personalizadas, registros personalizados, identificadores de usuários e exceções detectadas e não detectadas.

Para apps do Flutter, os relatórios de erros fatais são enviados ao Crashlytics em tempo real, sem que o usuário precise reiniciar o aplicativo. Os relatórios não fatais são gravados no disco para serem enviados com o próximo relatório de erros fatais ou quando o app for reiniciado.

Informar exceções não capturadas

Você pode capturar automaticamente todos os erros "fatais" gerados no framework do Flutter substituindo FlutterError.onError por FirebaseCrashlytics.instance.recordFlutterFatalError. Como alternativa, para também capturar exceções "não fatais", substitua FlutterError.onError por FirebaseCrashlytics.instance.recordFlutterError:

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

  await Firebase.initializeApp();
  bool weWantFatalErrorRecording = true;
  FlutterError.onError = (errorDetails) {
    if(weWantFatalErrorRecording){
      FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
    } else {
      FirebaseCrashlytics.instance.recordFlutterError(errorDetails);
    }
  };

  runApp(MyApp());
}

Erros assíncronos

Erros assíncronos não são capturados pelo framework do Flutter:

ElevatedButton(
  onPressed: () async {
    throw Error();
  }
  ...
)

Para detectar esses erros, use o gerenciador PlatformDispatcher.instance.onError:

Future<void> main() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    FlutterError.onError = (errorDetails) {
      FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails);
    };
    // Pass all uncaught asynchronous errors that aren't handled by the Flutter framework to Crashlytics
    PlatformDispatcher.instance.onError = (error, stack) {
      FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
      return true;
    };
    runApp(MyApp());

}

Erros de fora do Flutter

Para detectar erros que acontecem fora do contexto do Flutter, instale um listener de erros no Isolate atual:

Isolate.current.addErrorListener(RawReceivePort((pair) async {
  final List<dynamic> errorAndStacktrace = pair;
  await FirebaseCrashlytics.instance.recordError(
    errorAndStacktrace.first,
    errorAndStacktrace.last,
    fatal: true,
  );
}).sendPort);

Informar exceções capturadas

Além de reportar automaticamente as falhas do seu app, o Crashlytics permite registrar exceções não fatais e enviar elas para você na próxima vez que um evento fatal for relatado ou quando o app for reiniciado.

Use o método recordError para registrar exceções não fatais nos blocos catch do app. Exemplo:

await FirebaseCrashlytics.instance.recordError(
  error,
  stackTrace,
  reason: 'a non-fatal error'
);

// Or you can use:
await FirebaseCrashlytics.instance.recordFlutterError(errorDetails);

Também é possível registrar mais informações sobre o erro usando a propriedade information:

await FirebaseCrashlytics.instance.recordError(
  error,
  stackTrace,
  reason: 'a non-fatal error',
  information: ['further diagnostic information about the error', 'version 2.0'],
);

Essas exceções aparecem como problemas não fatais no Console do Firebase. O resumo do problema contém todas as informações de estado que você normalmente recebe com as falhas, além de detalhamentos por versão do dispositivo de hardware.

O Crashlytics processa exceções em uma linha de execução dedicada em segundo plano para minimizar o impacto no desempenho do app. Para reduzir o tráfego de rede dos usuários, o Crashlytic vai limitar a taxa do número de relatórios enviados do dispositivo, se necessário.

Adicionar chaves personalizadas

As chaves personalizadas ajudam você a chegar ao estado específico do seu aplicativo que está gerando uma falha. É possível associar pares de chave-valor arbitrários aos seus relatórios de erros e usar as chaves personalizadas para pesquisar e filtrar relatórios de erros no Console do Firebase.

  • No painel do Crashlytics, é possível pesquisar problemas que correspondam a uma chave personalizada.

  • Ao analisar um problema específico no console, você pode ver as chaves personalizadas associadas a cada evento (subguia Chaves) e até mesmo filtrar os eventos por chaves personalizadas (Filtro, na parte de cima da página).

Use o método de instância setCustomKey para definir pares de chave-valor. Veja alguns exemplos:

// Set a key to a string.
FirebaseCrashlytics.instance.setCustomKey('str_key', 'hello');

// Set a key to a boolean.
FirebaseCrashlytics.instance.setCustomKey("bool_key", true);

// Set a key to an int.
FirebaseCrashlytics.instance.setCustomKey("int_key", 1);

// Set a key to a long.
FirebaseCrashlytics.instance.setCustomKey("int_key", 1L);

// Set a key to a float.
FirebaseCrashlytics.instance.setCustomKey("float_key", 1.0f);

// Set a key to a double.
FirebaseCrashlytics.instance.setCustomKey("double_key", 1.0);

Adicionar mensagens de registro personalizadas

Para dar mais contexto aos eventos que geram uma falha, adicione registros personalizados do Crashlytics ao seu app. O Crashlytics associa os registros aos dados de falhas e exibe eles no Console do Firebase, na guia Registros do Crashlytics.

Use log para ajudar a identificar problemas. Exemplo:

FirebaseCrashlytics.instance.log("Higgs-Boson detected! Bailing out");

Definir identificadores de usuários

Para diagnosticar um problema, muitas vezes é útil saber quais usuários observaram uma determinada falha. O Crashlytics inclui uma maneira de identificar anonimamente os usuários nos relatórios de erros.

Para adicionar IDs de usuários aos seus relatórios, atribua a cada usuário um identificador exclusivo na forma de um número de ID, token ou valor de hash:

FirebaseCrashlytics.instance.setUserIdentifier("12345");

Se você precisar apagar um identificador de usuário depois de configurá-lo, redefina o valor deixando uma string em branco. Limpar um identificador de usuário não remove os registros atuais do Crashlytics. Se você precisar excluir registros associados a um ID de usuário, entre em contato com o suporte do Firebase.

Ative a permissão para geração de relatórios

Por padrão, o Crashlytics coleta automaticamente relatórios de erros para todos os usuários do seu app. Caso queira dar aos usuários mais controle sobre os dados enviados, é possível ativar a geração de relatórios. Para fazer isso, basta desativar a geração automática de relatórios e enviar dados ao Crashlytics somente quando você escolher no seu código:

  1. Desative a coleta automática de forma nativa:

    Plataformas da Apple

    Adicione uma nova chave ao arquivo Info.plist:

    • Chave: FirebaseCrashlyticsCollectionEnabled
    • Valor: false

    Android

    No bloco application do arquivo AndroidManifest.xml, adicione uma tag meta-data para desativar a coleta automática:

    <meta-data
        android:name="firebase_crashlytics_collection_enabled"
        android:value="false" />
    
  2. Para ativar a coleta nos usuários selecionados, chame a modificação da coleta de dados do Crashlytics no ambiente de execução.

    O valor de modificação continua entre os lançamentos do seu app. Assim, o Crashlytics pode coletar relatórios automaticamente. Para desativar o relatório automático de falhas, transmita false como o valor de modificação. Quando definido como false, o novo valor não se aplica até a próxima execução do app.

    FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
    

Gerenciar dados do Crash Insights

Com o Crash Insights, você soluciona problemas quando compara stack traces anônimos a traces de outros aplicativos do Firebase. Você receberá um aviso se o problema fizer parte de uma tendência maior. Para muitos problemas, o Crash Insights também oferece recursos para ajudar a depurar a falha.

Ele usa dados de falhas agregados para identificar tendências de estabilidade comuns. Caso prefira não compartilhar os dados do app, é possível desativar o Crash Insights no menu com o mesmo nome na parte de cima da lista de problemas do Crashlytics no Console do Firebase.