Receber relatórios de erros do Android NDK

Se o app Android tiver bibliotecas nativas, será possível ativar stack traces completos e relatórios detalhados de erros para seu código nativo no Firebase Crashlytics com algumas pequenas atualizações na configuração do build do seu app.

Neste guia, você verá como configurar relatórios de erros com o SDK do Firebase Crashlytics para NDK.

Se você estiver procurando informações para começar a usar o Crashlytics nos seus projetos do Unity, confira este guia para iniciantes.

Antes de começar

  1. Adicione o Firebase ao projeto para Android, caso ainda não tenha feito isso. Se você não tiver um app Android, faça o download de um app de exemplo.

  2. Recomendado: para ter recursos como usuários sem falhas, registros de navegação estrutural e alertas de velocidade, ative o Google Analytics no seu projeto do Firebase.

    • Caso seu projeto do Firebase não tenha o Google Analytics ativado, faça a ativação na guia Integrações das suas > Configurações do projeto no Console do Firebase.

    • Se você estiver criando um novo projeto do Firebase, ative o Google Analytics durante o fluxo de trabalho de criação do projeto.

Etapa 1: adicionar ao seu app o SDK do Crashlytics para NDK

No arquivo Gradle do módulo (nível do app) (geralmente <project>/<app-module>/build.gradle), adicione a dependência da biblioteca Android do Crashlytics para NDK. No gerenciamento do controle de versões das bibliotecas, recomendamos usar a BoM do Firebase para Android.

Para uma experiência ideal com o Crashlytics, recomendamos ativar o Google Analytics no seu projeto e adicionar o SDK do Firebase para Analytics ao seu app.

Kotlin+KTX

dependencies {
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:32.1.0')

    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-crashlytics-ndk'
    implementation 'com.google.firebase:firebase-analytics-ktx'
}

Com a BoM do Firebase para Android, seu app sempre vai usar versões compatíveis das bibliotecas do Firebase para Android.

(Alternativa) Adicionar dependências das bibliotecas do Firebase sem usar a BoM

Se você preferir não usar a BoM do Firebase, especifique cada versão das bibliotecas do Firebase na linha de dependência correspondente.

Se você usa várias bibliotecas do Firebase no seu app, recomendamos utilizar a BoM para gerenciar as versões delas, porque isso ajuda a garantir a compatibilidade de todas as bibliotecas.

dependencies {
    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When NOT using the BoM, you must specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-crashlytics-ndk:18.3.7'
    implementation 'com.google.firebase:firebase-analytics-ktx:21.3.0'
}

Java

dependencies {
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:32.1.0')

    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-crashlytics-ndk'
    implementation 'com.google.firebase:firebase-analytics'
}

Com a BoM do Firebase para Android, seu app sempre vai usar versões compatíveis das bibliotecas do Firebase para Android.

(Alternativa) Adicionar dependências das bibliotecas do Firebase sem usar a BoM

Se você preferir não usar a BoM do Firebase, especifique cada versão das bibliotecas do Firebase na linha de dependência correspondente.

Se você usa várias bibliotecas do Firebase no seu app, recomendamos utilizar a BoM para gerenciar as versões delas, porque isso ajuda a garantir a compatibilidade de todas as bibliotecas.

dependencies {
    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When NOT using the BoM, you must specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-crashlytics-ndk:18.3.7'
    implementation 'com.google.firebase:firebase-analytics:21.3.0'
}

Etapa 2: adicionar ao seu app o plug-in do Gradle para Crashlytics

  1. No arquivo Gradle no nível raiz do projeto (<project>/build.gradle), adicione o plug-in do Gradle para Crashlytics como uma dependência do buildscript:

    buildscript {
        repositories {
          // Make sure that you have the following two repositories
          google()  // Google's Maven repository
          mavenCentral()  // Maven Central repository
        }
    
        dependencies {
            ...
            classpath 'com.android.tools.build:gradle:7.2.0'
    
            // Make sure that you have the Google services Gradle plugin dependency
            classpath 'com.google.gms:google-services:4.3.15'
    
            // Add the dependency for the Crashlytics Gradle plugin
            classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.5'
        }
    }
  2. No arquivo Gradle do módulo (nível do app) (geralmente <project>/<app-module>/build.gradle), adicione o plug-in do Gradle para Crashlytics:

    plugins {
        id 'com.android.application'
    
        // Make sure that you have the Google services Gradle plugin
        id 'com.google.gms.google-services'
    
        // Add the Crashlytics Gradle plugin
        id 'com.google.firebase.crashlytics'
        ...
    }

Etapa 3: adicionar a extensão firebaseCrashlytics ao seu build

No arquivo do Gradle do módulo (nível do app), geralmente app/build.gradle, adicione a extensão firebaseCrashlytics.

Kotlin+KTX

// ...

android {
  // ...
  buildTypes {
      release {
          // Add this extension
          firebaseCrashlytics {
              // Enable processing and uploading of native symbols to Firebase servers.
              // By default, this is disabled to improve build speeds.
              // This flag must be enabled to see properly-symbolicated native
              // stack traces in the Crashlytics dashboard.
              nativeSymbolUploadEnabled true
          }
      }
  }
}

Java

// ...

android {
  // ...
  buildTypes {
      release {
          // Add this extension
          firebaseCrashlytics {
              // Enable processing and uploading of native symbols to Firebase servers.
              // By default, this is disabled to improve build speeds.
              // This flag must be enabled to see properly-symbolicated native
              // stack traces in the Crashlytics dashboard.
              nativeSymbolUploadEnabled true
          }
      }
  }
}

Etapa 4: configurar o upload automático de símbolos nativos

Para produzir stack traces legíveis usando falhas do NDK, o Crashlytics precisa saber sobre os símbolos nos seus binários nativos. O plug-in do Gradle para Crashlytics inclui a tarefa uploadCrashlyticsSymbolFileBUILD_VARIANT para automatizar esse processo.

  1. Para acessar a tarefa de upload automático de símbolos, verifique se nativeSymbolUploadEnabled está definido como true no arquivo Gradle do seu módulo no app.

  2. Para que os nomes dos métodos apareçam nos stack traces, é necessário invocar explicitamente a tarefa uploadCrashlyticsSymbolFileBUILD_VARIANT após cada build da biblioteca do NDK. Exemplo:

    >./gradlew app:assembleBUILD_VARIANT\
               app:uploadCrashlyticsSymbolFileBUILD_VARIANT
    
  3. O SDK do Crashlytics para NDK e o plug-in do Gradle para Crashlytics dependem da presença do ID do build do GNU nos objetos compartilhados nativos.

    Verifique a presença desse ID executando readelf -n em cada binário. Se o ID do build estiver ausente, adicione -Wl,--build-id às sinalizações do sistema de build para corrigir o problema.

Etapa 5: forçar uma falha no teste para concluir a configuração

Para concluir a configuração do Crashlytics e ver os dados iniciais no painel do Console do Firebase, é necessário forçar uma falha de teste.

  1. Adicione um código ao app que possa ser usado para forçar uma falha no teste.

    É possível usar o código a seguir no MainActivity do seu app para adicionar um botão que, quando pressionado, causa uma falha. O botão é chamado de "Testar falha".

    Kotlin+KTX

    val crashButton = Button(this)
    crashButton.text = "Test Crash"
    crashButton.setOnClickListener {
       throw RuntimeException("Test Crash") // Force a crash
    }
    
    addContentView(crashButton, ViewGroup.LayoutParams(
           ViewGroup.LayoutParams.MATCH_PARENT,
           ViewGroup.LayoutParams.WRAP_CONTENT))
    

    Java

    Button crashButton = new Button(this);
    crashButton.setText("Test Crash");
    crashButton.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
           throw new RuntimeException("Test Crash"); // Force a crash
       }
    });
    
    addContentView(crashButton, new ViewGroup.LayoutParams(
           ViewGroup.LayoutParams.MATCH_PARENT,
           ViewGroup.LayoutParams.WRAP_CONTENT));
    
  2. Crie e execute seu app.

  3. Force a falha de teste para enviar o primeiro relatório de erros do app:

    1. Abra o app no dispositivo ou emulador de teste.

    2. No app, pressione o botão "Testar falha" que você adicionou usando o código acima.

    3. Depois que o app falhar, reinicie-o para que ele possa enviar o relatório de falhas ao Firebase.

  4. Acesse o painel do Crashlytics no Console do Firebase para ver a falha do teste.

    Se você atualizou o console e ainda não consegue ver a falha de teste após cinco minutos, ative a geração de registros de depuração para ver se o app está enviando relatórios de falha.


Pronto. O Crashlytics agora está monitorando seu app em busca de falhas. Você também pode conferir e investigar relatórios de erros e estatísticas no painel do Crashlytics.

Próximas etapas

  • (Recomendado) Receba ajuda para depurar falhas causadas por erros de memória nativa coletando relatórios do GWP-ASan. Esses erros relacionados à memória podem ser associados à corrupção da memória no seu app, que é a principal causa de vulnerabilidades de segurança. Para aproveitar esse recurso, seu app precisa ter o GWP-ASan ativado explicitamente e usar o SDK do Crashlytics para NDK mais recente (v18.3.6+ ou a BoM do Firebase v31.3.0+).

  • Para personalizar a configuração do relatório de erros, adicione relatórios de ativação, registros, chaves e rastreamento de erros não fatais.

  • Faça a integração com o Google Play para filtrar os relatórios de erros do app Android pela faixa do Google Play diretamente no painel do Crashlytics. Isso permite que você configure o painel para verificar versões específicas.

Solução de problemas

Se você estiver vendo stack traces diferentes no Console do Firebase e no Logcat, consulte o Guia de solução de problemas.



Opções alternativas para o upload de símbolos

O fluxo de trabalho principal na página acima se aplica a builds padrão do Gradle. No entanto, alguns apps usam configurações ou ferramentas diferentes, como um processo de compilação que não seja o Gradle. Nessas situações, as opções a seguir podem ser úteis para o upload dos símbolos.

Opção: fazer upload de símbolos para módulos de biblioteca e dependências externas

Essa opção pode ser útil nas seguintes situações:

  • Se você usa um processo personalizado de compilação do NDK no Gradle
  • Caso suas bibliotecas nativas sejam criadas em um módulo de recurso/biblioteca ou fornecidas por um terceiro
  • Se a tarefa de upload automático de símbolos estiver falhando ou você estiver vendo falhas não simbolizadas no painel

Opção: fazer upload de símbolos para builds que não sejam do Gradle ou bibliotecas nativas com símbolos inacessíveis

Essa opção pode ser útil nas seguintes situações:

  • Se você usa um processo de compilação diferente do Gradle

  • Se as bibliotecas nativas com símbolos forem fornecidas de uma maneira que impeça o acesso a elas durante os builds do Gradle