Entenda as falhas de um jogo Unity usando recursos avançados do Crashlytics

1. Introdução

Neste codelab, você aprenderá a usar recursos avançados do Crashlytics, que proporcionarão melhor visibilidade das falhas e das circunstâncias que podem tê-las causado.

Você adicionará novas funcionalidades a um jogo de amostra, MechaHamster: Level Up with Firebase Edition . Este jogo de amostra é uma nova versão do clássico jogo Firebase MechaHamster que remove a maior parte de sua funcionalidade integrada do Firebase, dando a você a oportunidade de implementar novos usos do Firebase em seu lugar.

Você adicionará um menu de depuração ao jogo. Este menu de depuração chama métodos que você criará e permite exercitar as diferentes funcionalidades do Crashlytics. Esses métodos mostrarão como anotar seus relatórios automáticos de falhas com chaves personalizadas, logs personalizados, erros não fatais e muito mais.

Depois de construir o jogo, você usará o menu de depuração e inspecionará os resultados para entender a visão única que eles fornecem sobre como o jogo funciona em estado selvagem.

O que você aprenderá

  • Os tipos de erros detectados automaticamente pelo Crashlytics.
  • Erros adicionais que podem ser registrados propositalmente.
  • Como adicionar mais informações a esses erros para torná-los mais fáceis de entender.

O que você precisará

  • Unity (versão mínima recomendada 2019+) com um ou ambos os seguintes:
    • Suporte para compilação iOS
    • Suporte para compilação Android
  • (Somente para Android) Firebase CLI (usada para fazer upload de símbolos para relatórios de erros)

2. Configure seu ambiente de desenvolvimento

As seções a seguir descrevem como fazer download do código do Level Up with Firebase e abri-lo no Unity.

Observe que este jogo de amostra Level Up with Firebase é usado por vários outros codelabs Firebase + Unity, então talvez você já tenha concluído as tarefas nesta seção. Nesse caso, você pode ir diretamente para a última etapa desta página: "Adicionar SDKs do Firebase para Unity".

Baixe o código

Clone o repositório GitHub deste codelab na linha de comando:

git clone https://github.com/firebase/level-up-with-firebase.git

Alternativamente, se você não tiver o git instalado, poderá baixar o repositório como um arquivo ZIP .

Abra Level Up com Firebase no editor Unity

  1. Inicie o Unity Hub e, na guia Projetos , clique na seta suspensa ao lado de Abrir .
  2. Clique em Adicionar projeto do disco .
  3. Navegue até o diretório que contém o código e clique em OK .
  4. Se solicitado, selecione uma versão do editor Unity para usar e sua plataforma de destino (Android ou iOS).
  5. Clique no nome do projeto, level-up-with-firebase e o projeto será aberto no editor Unity.
  6. Se o seu editor não abri-lo automaticamente, abra MainGameScene em Assets > Hamster na guia Project do Unity Editor.
    ff4ea3f3c0d29379.png

Para obter mais informações sobre como instalar e usar o Unity, consulte Trabalhando no Unity .

3. Adicione o Firebase ao seu projeto Unity

Crie um projeto do Firebase

  1. No console do Firebase , clique em Adicionar projeto .
  2. Para criar um novo projeto, insira o nome do projeto desejado.
    Isso também definirá o ID do projeto (exibido abaixo do nome do projeto) como algo baseado no nome do projeto. Opcionalmente, você pode clicar no ícone de edição no ID do projeto para personalizá-lo ainda mais.
  3. Se solicitado, revise e aceite os termos do Firebase .
  4. Clique em Continuar .
  5. Selecione a opção Ativar Google Analytics para este projeto e clique em Continuar .
  6. Selecione uma conta existente do Google Analytics para usar ou selecione Criar uma nova conta para criar uma nova conta.
  7. Clique em Criar projeto .
  8. Quando o projeto for criado, clique em Continuar .

Registre seu aplicativo no Firebase

  1. Ainda no console do Firebase , no centro da página de visão geral do projeto, clique no ícone do Unity para iniciar o fluxo de trabalho de configuração ou, se você já adicionou um aplicativo ao seu projeto do Firebase, clique em Adicionar aplicativo para exibir as opções da plataforma.
  2. Selecione para registrar os destinos de compilação Apple (iOS) e Android.
  3. Insira os IDs específicos da plataforma do seu projeto Unity. Para este codelab, insira o seguinte:
  4. (Opcional) Insira os apelidos específicos da plataforma do seu projeto Unity.
  5. Clique em Registrar aplicativo e prossiga para a seção Baixar arquivo de configuração .

Adicionar arquivos de configuração do Firebase

Depois de clicar em Register app , você será solicitado a baixar dois arquivos de configuração (um arquivo de configuração para cada destino de compilação). Seu projeto do Unity precisa dos metadados do Firebase nesses arquivos para se conectar ao Firebase.

  1. Baixe os dois arquivos de configuração disponíveis:
    • Para Apple (iOS) : Baixe GoogleService-Info.plist .
    • Para Android : Baixe google-services.json .
  2. Abra a janela Projeto do seu projeto Unity e mova os dois arquivos de configuração para a pasta Assets .
  3. De volta ao console do Firebase, no fluxo de trabalho de configuração, clique em Avançar e prossiga para Adicionar SDKs do Firebase para Unity.

Adicionar SDKs do Firebase para Unity

  1. Clique em Baixar Firebase Unity SDK no console do Firebase.
  2. Descompacte o SDK em algum lugar conveniente.
  3. Em seu projeto Unity aberto, navegue até Assets > Import Package > Custom Package .
  4. Na caixa de diálogo Importar pacote , navegue até o diretório que contém o SDK descompactado, selecione FirebaseAnalytics.unitypackage e clique em Abrir .
  5. Na caixa de diálogo Importar pacote do Unity que aparece, clique em Importar .
  6. Repita as etapas anteriores para importar FirebaseCrashlytics.unitypackage .
  7. Retorne ao console do Firebase e, no fluxo de trabalho de configuração, clique em Avançar .

Para obter mais informações sobre como adicionar SDKs do Firebase a projetos do Unity, consulte Opções adicionais de instalação do Unity .

4. Configure o Crashlytics em seu projeto Unity

Para usar o Crashlytics em projetos do Unity, você precisará executar mais algumas etapas de configuração. Claro, você precisará inicializar o SDK. Mas também, você precisará fazer upload de seus símbolos para poder ver stacktraces simbolizados no console do Firebase e forçar uma falha de teste para garantir que o Firebase esteja recebendo seus eventos de falha.

Inicialize o SDK do Crashlytics

  1. Em Assets/Hamster/Scripts/MainGame.cs , adicione as seguintes instruções using :
    using Firebase.Crashlytics;
    using Firebase.Extensions;
    
    O primeiro módulo permite usar métodos do SDK do Crashlytics e o segundo contém algumas extensões para a API de tarefas C# . Sem ambas as instruções using , o código a seguir não funcionará.
  2. Ainda em MainGame.cs , adicione a inicialização do Firebase ao método Start() existente chamando InitializeFirebaseAndStartGame() :
    void Start()
    {
      Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
      InitializeFirebaseAndStartGame();
    }
    
  3. E novamente, em MainGame.cs , encontre InitializeFirebaseAndStartGame() , declare uma variável de aplicativo e, em seguida, substitua a implementação do método assim:
    public Firebase.FirebaseApp app = null;
    
    // Begins the firebase initialization process and afterwards, opens the main menu.
    private void InitializeFirebaseAndStartGame()
    {
      Firebase.FirebaseApp.CheckAndFixDependenciesAsync()
      .ContinueWithOnMainThread(
        previousTask => 
        {
          var dependencyStatus = previousTask.Result;
          if (dependencyStatus == Firebase.DependencyStatus.Available) {
            // Create and hold a reference to your FirebaseApp,
            app = Firebase.FirebaseApp.DefaultInstance;
            // Set the recommended Crashlytics uncaught exception behavior.
            Crashlytics.ReportUncaughtExceptionsAsFatal = true;
            InitializeCommonDataAndStartGame();
          } else {
            UnityEngine.Debug.LogError(
              $"Could not resolve all Firebase dependencies: {dependencyStatus}\n" +
              "Firebase Unity SDK is not safe to use here");
          }
        });
    }
    

Colocar a lógica de inicialização aqui evita a interação do jogador antes que as dependências do Firebase sejam inicializadas.

Os benefícios e efeitos de relatar exceções não tratadas como fatais são discutidos nas Perguntas frequentes do Crashlytics .

Construa seu projeto e carregue símbolos

As etapas para criar e fazer upload de símbolos são diferentes para aplicativos iOS e Android.

iOS+ (plataforma Apple)

  1. Na caixa de diálogo Build Settings , exporte seu projeto para um espaço de trabalho Xcode.
  2. Crie seu aplicativo.
    Para plataformas Apple, o plug-in Firebase Unity Editor configura automaticamente seu projeto Xcode para gerar e fazer upload de um arquivo de símbolo compatível com Crashlytics para servidores Firebase para cada build. Essas informações de símbolos são necessárias para ver rastreamentos de pilha simbolizados no painel do Crashlytics.

Android

  1. (apenas durante a configuração inicial, não para cada compilação) Configure sua compilação:
    1. Crie uma nova pasta chamada Builds na raiz do diretório do seu projeto (ou seja, como irmã do diretório Assets ) e, a seguir, crie uma subpasta chamada Android .
    2. Em File > Build Settings > Player Settings > Configuration , defina Scripting Backend como IL2CPP.
      • O IL2CPP geralmente faz com que as compilações sejam menores e tenham melhor desempenho.
      • IL2CPP também é a ÚNICA opção disponível no iOS e selecioná-lo aqui permite que as duas plataformas tenham melhor paridade e simplifique as diferenças de depuração entre as duas (se você optar por construir ambas).
  2. Crie seu aplicativo. Em File > Build Settings , conclua o seguinte:
    1. Certifique-se de que Criar símbolos.zip esteja marcado (ou se for apresentado um menu suspenso, selecione Depuração ).
    2. Crie seu APK diretamente do Unity Editor na subpasta Builds/Android que você acabou de criar.
  3. Assim que sua compilação for concluída, você precisará gerar um arquivo de símbolo compatível com Crashlytics e carregá-lo nos servidores Firebase. Essas informações de símbolos são necessárias para ver rastreamentos de pilha simbolizados para falhas de biblioteca nativa no painel do Crashlytics.

    Gere e faça upload deste arquivo de símbolos executando o seguinte comando Firebase CLI :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
    • FIREBASE_APP_ID : seu ID do aplicativo Android do Firebase (não o nome do seu pacote). Encontre esse valor no arquivo google-services.json que você baixou anteriormente. É o valor mobilesdk_app_id .
      Exemplo de ID do aplicativo Android do Firebase: 1:567383003300:android:17104a2ced0c9b9b
    • PATH/TO/SYMBOLS : o caminho do arquivo de símbolo compactado gerado no diretório Builds/Android quando sua compilação foi concluída (por exemplo: Builds/Android/myapp-1.0-v100.symbols.zip ).

Forçar uma falha de teste para concluir a configuração

Para concluir a configuração do Crashlytics e ver os dados iniciais no painel do Crashlytics do console do Firebase, você precisa forçar uma falha de teste.

  1. No MainGameScene encontre o EmptyObject GameObject no editor Hierarchy , adicione o seguinte script a ele e salve a cena. Este script causará uma falha no teste alguns segundos após a execução do aplicativo.
    using System;
    using UnityEngine;
    
    public class CrashlyticsTester : MonoBehaviour {
        // Update is called once per frame
        void Update()
        {
            // Tests your Crashlytics implementation by
            // throwing an exception every 60 frames.
            // You should see reports in the Firebase console
            // a few minutes after running your app with this method.
            if(Time.frameCount >0 && (Time.frameCount%60) == 0)
            {
                throw new System.Exception("Test exception; please ignore");
            }
        }
    }
    
  2. Crie seu aplicativo e carregue as informações do símbolo após a conclusão da construção.
    • iOS : o plug-in Firebase Unity Editor configura automaticamente seu projeto Xcode para fazer upload de seu arquivo de símbolo.
    • Android : execute o comando crashlytics:symbols:upload CLI do Firebase para fazer upload do arquivo de símbolo.
  3. Execute seu aplicativo. Assim que seu aplicativo estiver em execução, observe o log do dispositivo e aguarde o disparo da exceção do CrashlyticsTester .
    • iOS : visualize os logs no painel inferior do Xcode.
    • Android : visualize os logs executando o seguinte comando no terminal: adb logcat .
  4. Visite o painel do Crashlytics para ver a exceção! Você o verá na tabela Problemas na parte inferior do painel. Posteriormente no codelab, você aprenderá mais sobre como explorar esses relatórios.
  5. Depois de confirmar que o evento foi carregado no Crashlytics, selecione o EmptyObject GameObject ao qual você o anexou, remova apenas o componente CrashlyticsTester e salve a cena para restaurá-la à sua condição original.

5. Habilite e entenda o menu de depuração

Até agora, você adicionou o Crashlytics ao seu projeto do Unity, concluiu a configuração e confirmou que o SDK do Crashlytics está fazendo upload de eventos para o Firebase. Agora você criará um menu em seu projeto Unity que demonstrará como usar funcionalidades mais avançadas do Crashlytics em seu jogo. O projeto Level Up with Firebase Unity já possui um menu de depuração oculto que você tornará visível e para o qual escreverá a funcionalidade.

Habilite o menu de depuração

O botão para acessar o menu Debug existe no seu projeto Unity, mas não está habilitado no momento. Você deve ativar o botão para acessá-lo no pré-fabricado MainMenu :

  1. No Unity Editor, abra o pré-fabricado chamado MainMenu . 4148538cbe9f36c5.png
  2. Na hierarquia pré-fabricada, encontre o subobjeto desabilitado chamado DebugMenuButton e selecione-o. 816f8f9366280f6c.png
  3. Habilite o DebugMenuButton marcando a caixa no canto superior esquerdo à esquerda do campo de texto que contém DebugMenuButton . 8a8089d2b4886da2.png
  4. Salve a pré-fabricada.
  5. Execute o jogo no editor ou no seu dispositivo. O menu agora deve estar acessível.

Visualize e entenda os corpos dos métodos do menu Debug

Posteriormente neste codelab, você escreverá corpos de métodos para alguns métodos de depuração pré-configurados do Crashlytics. No entanto, no projeto Level Up with Firebase Unity, os métodos são definidos e chamados em DebugMenu.cs .

Embora alguns desses métodos chamem métodos do Crashlytics e gerem erros, a capacidade do Crashlytics de detectar esses erros não depende de chamar esses métodos primeiro. Em vez disso, os relatórios de falhas gerados pela detecção automática de erros serão aprimorados pelas informações adicionadas por esses métodos.

Abra DebugMenu.cs e encontre os seguintes métodos:

Métodos para gerar e anotar problemas do Crashlytics:

  • CrashNow
  • LogNonfatalError
  • LogStringsAndCrashNow
  • SetAndOverwriteCustomKeyThenCrash
  • SetLogsAndKeysBeforeANR

Métodos para registrar eventos do Analytics para auxiliar na depuração:

  • LogProgressEventWithStringLiterals
  • LogIntScoreWithBuiltInEventAndParams

Nas etapas posteriores deste codelab, você implementará esses métodos e aprenderá como eles ajudam a resolver situações específicas que podem ocorrer no desenvolvimento de jogos.

6. Garantir a entrega de relatórios de falhas em desenvolvimento

Antes de começar a implementar esses métodos de depuração e ver como eles afetam os relatórios de falhas, certifique-se de entender como os eventos são relatados ao Crashlytics.

Para projetos Unity, os eventos de falha e exceção no jogo são imediatamente gravados no disco. Para exceções não detectadas que não travam o jogo (por exemplo, exceções C# não detectadas na lógica do jogo), você pode fazer com que o SDK do Crashlytics as relate como eventos fatais definindo a propriedade Crashlytics.ReportUncaughtExceptionsAsFatal como true onde você inicializa o Crashlytics no seu projeto do Unity . Esses eventos são relatados ao Crashlytics em tempo real, sem a necessidade de o usuário final reiniciar o jogo. Observe que travamentos nativos são sempre relatados como eventos fatais e enviados quando um usuário final reinicia o jogo.

Além disso, esteja ciente das seguintes diferenças pequenas, mas significativas, entre como os diferentes ambientes de execução enviam informações do Crashlytics para o Firebase:

Simulador iOS:

  • As informações do Crashlytics serão relatadas se e somente se você desconectar o Xcode do simulador. Se o Xcode estiver anexado, ele detecta os erros no upstream, impedindo a entrega de informações.

Dispositivos físicos móveis (Android e iOS):

  • Específico do Android: os ANRs são relatados apenas no Android 11+. ANRs e eventos não fatais são relatados na próxima execução.

Editor da Unidade:

Teste o travamento do seu jogo com o toque de um botão no CrashNow()

Depois que o Crashlytics é configurado no seu jogo, o SDK do Crashlytics registra automaticamente falhas e exceções não detectadas e as envia ao Firebase para análise. E os relatórios são exibidos no painel do Crashlytics no console do Firebase.

  1. Para demonstrar que isso é realmente automático: abra DebugMenu.cs e substitua o método CrashNow() da seguinte forma:
    void CrashNow()
    {
        TestCrash();
    }
    
  2. Crie seu aplicativo.
  3. (Somente Android) Faça upload dos seus símbolos executando o seguinte comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Toque no botão Crash Now e prossiga para a próxima etapa deste codelab para descobrir como visualizar e interpretar o relatório de falhas.

7. Entenda os relatórios de problemas no console do Firebase

Quando se trata de visualizar seus relatórios de falhas, você precisa saber um pouco mais sobre como aproveitá-los ao máximo. Cada um dos métodos que você escrever mostrará como adicionar diferentes tipos de informações aos relatórios do Crashlytics.

  1. Toque no botão Crash Now e reinicie seu aplicativo.
  2. Vá para o painel do Crashlytics . Role para baixo até a tabela Problemas na parte inferior do painel, onde o Crashlytics agrupa eventos que têm a mesma causa raiz em "problemas".
  3. Clique no novo problema listado na tabela Problemas . Isso exibe o resumo do evento sobre cada evento individual que foi enviado ao Firebase.

    Você deverá ver algo como a captura de tela a seguir. Observe como o resumo do evento apresenta com destaque o rastreamento de pilha da chamada que levou à falha. 40c96abe7f90c3aa.png

Metadados adicionais

Outra guia útil é a guia Unity Metadata . Esta seção informa sobre os atributos do dispositivo no qual o evento ocorreu, incluindo recursos físicos, modelo/especificações da CPU e todos os tipos de métricas de GPU.

Aqui está um exemplo em que as informações nesta guia podem ser úteis:
Imagine que seu jogo faz uso intenso de shaders para obter uma determinada aparência, mas nem todos os telefones possuem GPUs capazes de renderizar esse recurso. As informações na guia Metadados do Unity podem dar uma ideia melhor de qual hardware seu aplicativo deve testar ao decidir quais recursos disponibilizar automaticamente ou desabilitar totalmente.

Embora um bug ou travamento possa nunca acontecer no seu dispositivo, devido à enorme diversidade de dispositivos Android disponíveis, ajuda a entender melhor os “pontos de acesso” específicos dos dispositivos do seu público.

41d8d7feaa87454d.png

8. Lançar, capturar e registrar uma exceção

Muitas vezes, como desenvolvedor, mesmo que seu código capture e trate adequadamente uma exceção de tempo de execução, é bom observar que ela ocorreu e em que circunstâncias. Crashlytics.LogException pode ser usado exatamente para esta finalidade: enviar um evento de exceção ao Firebase para que você possa depurar ainda mais o problema no console do Firebase.

  1. Em Assets/Hamster/Scripts/States/DebugMenu.cs , anexe o seguinte às instruções using :
    // Import Firebase
    using Firebase.Crashlytics;
    
  2. Ainda em DebugMenu.cs , substitua LogNonfatalError() da seguinte forma:
    void LogNonfatalError()
    {
        try
        {
            throw new System.Exception($"Test exception thrown in {nameof(LogNonfatalError)}");
        }
        catch(System.Exception exception)
        {
            Crashlytics.LogException(exception);
        }
    }
    
  3. Crie seu aplicativo.
  4. (Somente Android) Faça upload dos seus símbolos executando o seguinte comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  5. Toque no botão Registrar erro não fatal e reinicie o aplicativo.
  6. Acesse o painel do Crashlytics e você verá algo semelhante ao que viu na última etapa deste codelab.
  7. Desta vez, porém, restrinja o filtro Tipo de evento a Não fatais para que você visualize apenas erros não fatais, como aquele que acabou de registrar.
    a39ea8d9944cbbd9.png

9. Registre strings no Crashlytics para entender melhor o fluxo de execução do programa

Você já tentou descobrir por que uma linha de código chamada de vários caminhos, centenas, senão milhares de vezes por sessão, pode gerar repentinamente uma exceção ou falha? Embora possa ser bom percorrer o código em um IDE e observar os valores mais de perto, e se isso acontecer apenas entre uma porcentagem cada vez menor de seus usuários? Pior ainda, o que você faria se não conseguisse replicar essa falha, não importa o que fizesse?

Em situações como essa, ter algum contexto pode fazer muita diferença. Com Crashlytics.Log , você pode escrever o contexto necessário. Pense nessas mensagens como dicas para o seu futuro sobre o que pode estar acontecendo.

Embora os registros possam ser usados ​​de inúmeras maneiras, eles normalmente são mais úteis para registrar situações em que a ordem e/ou ausência de chamadas é uma informação de vital importância.

  1. Em Assets/Hamster/Scripts/States/DebugMenu.cs , substitua LogStringsAndCrashNow() da seguinte forma:
    void LogStringsAndCrashNow()
    {
        Crashlytics.Log($"This is the first of two descriptive strings in {nameof(LogStringsAndCrashNow)}");
        const bool RUN_OPTIONAL_PATH = false;
        if(RUN_OPTIONAL_PATH)
        {
            Crashlytics.Log(" As it stands, this log should not appear in your records because it will never be called.");
        }
        else
        {
            Crashlytics.Log(" A log that will simply inform you which path of logic was taken. Akin to print debugging.");
        }
        Crashlytics.Log($"This is the second of two descriptive strings in {nameof(LogStringsAndCrashNow)}");
        TestCrash();
    }
    
  2. Crie seu aplicativo.
  3. (Somente Android) Faça upload dos seus símbolos executando o seguinte comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Toque no botão Log Strings and Crash Now e reinicie seu aplicativo.
  5. Volte para o painel do Crashlytics e clique no problema mais recente listado na tabela Problemas . Novamente você deverá ver algo semelhante às edições anteriores.
    7aabe103b8589cc7.png
  6. No entanto, se você clicar na guia Logs em Event summary , terá uma visualização como esta:
    4e27aa407b7571cf.png

10. Escreva e substitua uma chave personalizada

Digamos que você queira entender melhor uma falha correspondente a variáveis ​​definidas com um pequeno número de valores ou configurações. Pode ser bom poder filtrar, com base na combinação de variáveis ​​e valores possíveis que você está observando, a qualquer momento.

Além de registrar strings arbitrárias, o Crashlytics oferece outra forma de depuração quando é benéfico saber o estado exato do seu programa quando ele travou: chaves personalizadas.

Esses são pares de valores-chave que você pode definir para uma sessão. Ao contrário dos registos que se acumulam e são puramente aditivos, as chaves podem ser substituídas para refletir apenas o estado mais recente de uma variável ou condição.

Além de serem um registro do último estado registrado do seu programa, essas chaves podem ser usadas como filtros poderosos para problemas do Crashlytics.

  1. Em Assets/Hamster/Scripts/States/DebugMenu.cs , substitua SetAndOverwriteCustomKeyThenCrash() da seguinte maneira:
    void SetAndOverwriteCustomKeyThenCrash()
    {
        const string CURRENT_TIME_KEY = "Current Time";
        System.TimeSpan currentTime = System.DateTime.Now.TimeOfDay;
        Crashlytics.SetCustomKey(
            CURRENT_TIME_KEY,
            DayDivision.GetPartOfDay(currentTime).ToString() // Values must be strings
            );
    
        // Time Passes
        currentTime += DayDivision.DURATION_THAT_ENSURES_PHASE_CHANGE;
    
        Crashlytics.SetCustomKey(
            CURRENT_TIME_KEY,
            DayDivision.GetPartOfDay(currentTime).ToString()
            );
        TestCrash();
    }
    
  2. Crie seu aplicativo.
  3. (Somente Android) Faça upload dos seus símbolos executando o seguinte comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Toque no botão Definir chave personalizada e travamento e reinicie o aplicativo.
  5. Volte para o painel do Crashlytics e clique no problema mais recente listado na tabela Problemas . Novamente você deverá ver algo semelhante às edições anteriores.
  6. Desta vez, porém, clique na guia Chaves no resumo do evento para poder visualizar o valor das chaves, incluindo Current Time :
    7dbe1eb00566af98.png

Por que você desejaria usar chaves personalizadas em vez de logs personalizados?

  • Os logs são bons para armazenar dados sequenciais, mas as chaves personalizadas são melhores se você quiser apenas o valor mais recente .
  • No console do Firebase, você pode filtrar facilmente os problemas pelos valores das chaves na caixa de pesquisa da tabela de problemas .

Porém, semelhante aos logs, as chaves personalizadas têm um limite. O Crashlytics oferece suporte a no máximo 64 pares de valores-chave. Depois de atingir esse limite, os valores adicionais não serão salvos. Cada par de valores-chave pode ter até 1 KB de tamanho.

11. (Somente Android) Use chaves e registros personalizados para entender e diagnosticar um ANR

Uma das classes de problemas mais difíceis de depurar para desenvolvedores Android é o erro Application Not Responding (ANR). Os ANRs ocorrem quando um aplicativo não responde à entrada por mais de cinco segundos. Se isso acontecer, significa que o aplicativo congelou ou está muito lento. Uma caixa de diálogo é mostrada aos usuários e eles podem escolher entre "Aguardar" ou "Fechar aplicativo".

Os ANRs são uma experiência ruim para o usuário e (conforme mencionado no link ANR acima) podem afetar a descoberta do seu aplicativo na Google Play Store. Devido à sua complexidade e porque geralmente são causados ​​por código multithread com comportamento muito diferente em diferentes modelos de telefone, reproduzir ANRs durante a depuração costuma ser muito difícil, se não quase impossível. Como tal, abordá-los de forma analítica e dedutiva é geralmente a melhor abordagem.

Neste método, usaremos uma combinação de Crashlytics.LogException , Crashlytics.Log e Crashlytics.SetCustomKey para complementar o registro automático de problemas e nos fornecer mais informações.

  1. Em Assets/Hamster/Scripts/States/DebugMenu.cs , substitua SetLogsAndKeysBeforeANR() da seguinte forma:
    void SetLogsAndKeysBeforeANR()
    {
        System.Action<string,long> WaitAndRecord =
        (string methodName, long targetCallLength)=>
        {
            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
            const string CURRENT_FUNCTION = "Current Async Function";
    
            // Initialize key and start timing
            Crashlytics.SetCustomKey(CURRENT_FUNCTION, methodName);
            stopWatch.Start();
    
            // The actual (simulated) work being timed.
            BusyWaitSimulator.WaitOnSimulatedBlockingWork(targetCallLength);
    
            // Stop timing
            stopWatch.Stop();
    
            if(stopWatch.ElapsedMilliseconds>=BusyWaitSimulator.EXTREME_DURATION_MILLIS)
            {
              Crashlytics.Log($"'{methodName}' is long enough to cause an ANR.");
            }
            else if(stopWatch.ElapsedMilliseconds>=BusyWaitSimulator.SEVERE_DURATION_MILLIS)
            {
              Crashlytics.Log($"'{methodName}' is long enough it may cause an ANR");
            }
        };
    
        WaitAndRecord("DoSafeWork",1000L);
        WaitAndRecord("DoSevereWork",BusyWaitSimulator.SEVERE_DURATION_MILLIS);
        WaitAndRecord("DoExtremeWork",2*BusyWaitSimulator.EXTREME_DURATION_MILLIS);
    }
    
  2. Crie seu aplicativo.
  3. Faça upload dos seus símbolos executando o seguinte comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Toque no botão denominado Definir registros e chaves → ANR e reinicie seu aplicativo.
  5. Volte para o painel do Crashlytics e clique no novo problema na tabela Problemas para visualizar o resumo do evento . Se a chamada for realizada corretamente, você verá algo assim:
    876c3cff7037bd07.png

    Como você pode ver, o Firebase identificou a espera ocupada no thread como o principal motivo pelo qual seu aplicativo acionou um ANR.
  6. Se você observar os logs na guia Logs do Resumo de eventos , verá que o último método registrado como concluído é DoSevereWork .
    5a4bec1cf06f6984.png

    Por outro lado, o último método listado como inicial é DoExtremeWork , o que indica que o ANR ocorreu durante esse método e o jogo foi fechado antes que pudesse registrar DoExtremeWork .

    89d86d5f598ecf3a.png

Por que fazer isso?

  • Reproduzir ANRs é incrivelmente difícil, portanto, ser capaz de obter informações valiosas sobre a área e as métricas do código é extremamente importante para descobri-las dedutivamente.
  • Com as informações armazenadas nas chaves personalizadas, agora você sabe qual thread assíncrono demorou mais para ser executado e quais corriam o risco de acionar ANRs. Esse tipo de dados lógicos e numéricos relacionados mostrará onde é mais necessário otimizar seu código.

12. Intercalando eventos de Analytics para enriquecer ainda mais os relatórios

Os métodos a seguir também podem ser chamados no menu Debug, mas em vez de gerarem problemas por si próprios, eles usam o Google Analytics como outra fonte de informações para entender melhor o funcionamento do seu jogo.

Ao contrário dos outros métodos escritos neste codelab, você deve usá-los em combinação com os outros. Chame esses métodos (pressionando o botão correspondente no menu Debug) em qualquer ordem arbitrária desejada antes de executar um dos outros. Então, ao examinar as informações no problema específico do Crashlytics, você verá um registro ordenado de eventos do Analytics. Esses dados podem ser usados ​​em um jogo para entender melhor uma combinação de fluxo de programa ou entrada do usuário, dependendo de como você instrumentou seu aplicativo.

  1. Em Assets/Hamster/Scripts/States/DebugMenu.cs , substitua as implementações existentes dos seguintes métodos:
    public void LogProgressEventWithStringLiterals()
    {
          Firebase.Analytics.FirebaseAnalytics.LogEvent("progress", "percent", 0.4f);
    }
    
    public void LogIntScoreWithBuiltInEventAndParams()
    {
          Firebase.Analytics.FirebaseAnalytics
            .LogEvent(
              Firebase.Analytics.FirebaseAnalytics.EventPostScore,
              Firebase.Analytics.FirebaseAnalytics.ParameterScore,
              42
            );
    }
    
  2. Crie e implante seu jogo e entre no menu Debug .
  3. (Somente Android) Faça upload dos seus símbolos executando o seguinte comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Pressione pelo menos um dos seguintes botões uma ou mais vezes para chamar as funções acima:
    • Evento de string de registro
    • Registrar evento interno
  5. Pressione o botão Crash Now .
  6. Reinicie o jogo para que ele carregue o evento de travamento no Firebase.
  7. Quando você registra várias sequências arbitrárias de eventos do Analytics e faz com que seu jogo gere um evento a partir do qual o Crashlytics cria um relatório (como você acabou de fazer), eles são adicionados à guia Logs do Resumo de eventos do Crashlytics assim:
    d3b16d78f76bfb04.png

13. Seguindo em frente

E com isso, você deverá ter uma base teórica melhor para complementar seus relatórios de falhas gerados automaticamente. Essas novas informações permitem que você use o estado atual, registros de eventos passados ​​e eventos existentes do Google Analytics para detalhar melhor a sequência de eventos e a lógica que levou ao seu resultado.

Se seu aplicativo for direcionado ao Android 11 (API de nível 30) ou superior, considere incorporar GWP-ASan , um recurso de alocador de memória nativo útil para depurar falhas causadas por erros de memória nativa, como bugs use-after-free e heap-buffer-overflow . Para aproveitar esse recurso de depuração, habilite explicitamente o GWP-ASan .

Próximos passos

Prossiga para o codelab Instrumentar seu jogo Unity com a Configuração remota , onde você aprenderá como usar a Configuração remota e os testes A/B no Unity.