Sobre este codelab
1. Introdução
Neste codelab, você vai aprender a usar recursos avançados do Crashlytics, que vão melhorar a visibilidade das falhas e das circunstâncias que podem ter causado elas.
Você vai adicionar novas funcionalidades a um jogo de exemplo, MechaHamster: suba de nível com o Firebase Edition. Esse jogo de exemplo é uma nova versão do jogo clássico MechaHamster do Firebase que remove a maioria das funcionalidades integradas do Firebase, dando a você a chance de implementar novos usos do Firebase.
Você vai adicionar um menu de depuração ao jogo. Esse menu de depuração chama métodos que você vai criar e permite testar as diferentes funcionalidades do Crashlytics. Esses métodos mostram como anotar seus relatórios de erros automáticos com chaves personalizadas, registros personalizados, erros não fatais e muito mais.
Depois de criar o jogo, use o menu de depuração e inspecione os resultados para entender a visão exclusiva que eles oferecem sobre como o jogo é executado.
O que você vai aprender
- Os tipos de erros que são detectados automaticamente pelo Crashlytics.
- Outros erros que podem ser registrados de propósito.
- Como adicionar mais informações a esses erros para facilitar a compreensão.
Pré-requisitos
- Unity (versão mínima recomendada 2019+) com um ou ambos os seguintes:
- Suporte a builds do iOS
- Suporte a builds do Android
- (Somente para Android) A CLI do Firebase (usada para fazer upload de símbolos para relatórios de erros)
- Siga as instruções para instalar a CLI do Firebase.
Se você já instalou a CLI, atualize para a versão mais recente.
- Siga as instruções para instalar a CLI do Firebase.
2. Configurar o ambiente de desenvolvimento
As seções a seguir descrevem como fazer o download do código do Level Up with Firebase e abri-lo no Unity.
Este jogo de exemplo Level Up with Firebase é usado por vários outros codelabs do Firebase + Unity. Portanto, é possível que você já tenha concluído as tarefas desta seção. Se sim, você pode ir diretamente para a última etapa desta página: "Adicionar SDKs do Firebase para Unity".
Fazer o download do código
Clone o repositório do GitHub deste codelab na linha de comando:
git clone https://github.com/firebase/level-up-with-firebase.git
Se o git não estiver instalado, faça o download do repositório como um arquivo ZIP.
Abra o Level Up com o Firebase no editor do Unity.
- Inicie o Unity Hub e, na guia Projects, clique na seta do menu suspenso ao lado de Open.
- Clique em Adicionar projeto do disco.
- Navegue até o diretório que contém o código e clique em OK.
- Se solicitado, selecione uma versão do editor do Unity e a plataforma de destino (Android ou iOS).
- Clique no nome do projeto, level-up-with-firebase, e ele será aberto no editor do Unity.
- Se o editor não abrir automaticamente, abra
MainGameScene
em Assets > Hamster na guia Project do Unity Editor.
Para mais informações sobre como instalar e usar o Unity, consulte Como trabalhar no Unity.
3. Adicionar o Firebase ao seu projeto do Unity
Criar um projeto do Firebase
- No Console do Firebase, clique em Adicionar projeto.
- Para criar um novo projeto, digite o nome dele.
Isso também vai definir o ID do projeto (exibido abaixo do nome do projeto) como algo baseado no nome do projeto. Se quiser, clique no ícone editar no ID do projeto para personalizar ainda mais. - Se solicitado, leia e aceite os Termos do Firebase.
- Clique em Continuar.
- Selecione a opção Ativar o Google Analytics para este projeto e clique em Continuar.
- Selecione uma conta do Google Analytics para usar ou clique em Criar uma conta.
- Clique em Criar projeto.
- Quando o projeto for criado, clique em Continuar.
Registrar o app no Firebase
- 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á tiver adicionado um app ao projeto do Firebase, clique em Adicionar app para mostrar as opções da plataforma.
- Selecione para registrar os destinos de build da Apple (iOS) e do Android.
- Digite os IDs específicos da plataforma do seu projeto do Unity. Neste codelab, insira o seguinte:
- Para a Apple (iOS): insira
com.google.firebase.level-up
no campo ID do pacote do iOS. - Para Android: insira
com.google.firebase.level_up
no campo Nome do pacote Android.
- Para a Apple (iOS): insira
- (Opcional) Digite os apelidos específicos da plataforma do seu projeto do Unity.
- Clique em Registrar app e prossiga para a seção Fazer o download do arquivo de configuração.
Adicionar arquivos de configuração do Firebase
Depois de clicar em Register app, você vai precisar fazer o download de dois arquivos de configuração (um para cada destino de build). O projeto do Unity precisa dos metadados do Firebase nesses arquivos para se conectar ao Firebase.
- Faça o download dos dois arquivos de configuração disponíveis:
- Para Apple (iOS): faça o download de GoogleService-Info.plist.
- Para Android: faça o download de google-services.json.
- Abra a janela Project do projeto do Unity e mova os dois arquivos de configuração para a pasta Assets.
- De volta ao Console do Firebase, no fluxo de trabalho de configuração, clique em Próxima e adicione os SDKs do Firebase para Unity.
Adicionar SDKs do Firebase para Unity
- Clique em Fazer o download do SDK do Firebase para Unity no Console do Firebase.
- Descompacte o SDK em um local prático.
- No projeto aberto do Unity, acesse Assets > Import Package > Custom Package.
- Na caixa de diálogo Import package, navegue até o diretório que contém o SDK descompactado, selecione
FirebaseAnalytics.unitypackage
e clique em Open. - Na caixa de diálogo Import Unity Package que aparece, clique em Import.
- Repita as etapas anteriores para importar
FirebaseCrashlytics.unitypackage
. - Volte ao Console do Firebase e, no fluxo de trabalho de configuração, clique em Próxima.
Para saber mais sobre como adicionar SDKs do Firebase a projetos do Unity, consulte Outras opções de instalação do Unity.
4. Configurar o Crashlytics no seu projeto do Unity
Para usar o Crashlytics em projetos Unity, você precisa seguir mais algumas etapas de configuração. É claro que você vai precisar inicializar o SDK. Além disso, você precisa fazer upload dos símbolos para conferir os stacktraces simbolizados no console do Firebase e forçar uma falha de teste para garantir que o Firebase esteja recebendo seus eventos de falha.
Inicializar o SDK do Crashlytics
- Em
Assets/Hamster/Scripts/MainGame.cs
, adicione as seguintes instruçõesusing
: O primeiro módulo permite usar métodos do SDK do Crashlytics, e o segundo contém algumas extensões para a API C# Tasks. Sem ambas as instruçõesusing Firebase.Crashlytics;
using Firebase.Extensions;using
, o código a seguir não vai funcionar. - Ainda em
MainGame.cs
, adicione a inicialização do Firebase ao métodoStart()
atual chamandoInitializeFirebaseAndStartGame()
:void Start()
{
Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
InitializeFirebaseAndStartGame();
} - Novamente, em
MainGame.cs
, encontreInitializeFirebaseAndStartGame()
, declare uma variável do app e substitua a implementação do método desta forma: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 impede a interação do jogador antes que as dependências do Firebase sejam inicializadas.
Os benefícios e efeitos de informar exceções não tratadas como fatais são discutidos nas Perguntas frequentes do Crashlytics.
Criar seu projeto e fazer upload de símbolos
As etapas para criar e fazer upload de símbolos são diferentes para apps iOS e Android.
iOS+ (plataforma Apple)
- Na caixa de diálogo Build Settings, exporte seu projeto para um espaço de trabalho do Xcode.
- Crie seu app.
Para plataformas Apple, o plug-in do Editor do Firebase para Unity configura automaticamente seu projeto do Xcode para gerar e fazer upload de um arquivo de símbolo compatível com o Crashlytics para os servidores do Firebase em cada build. Essas informações são necessárias para conferir stack traces simbolizados no painel do Crashlytics.
Android
- (somente durante a configuração inicial, não para cada build) Configurar o build:
- Crie uma nova pasta chamada Builds na raiz do diretório do projeto (ou seja, como um irmão do diretório Assets) e, em seguida, crie uma subpasta chamada Android.
- Em File > Build Settings > Player Settings > Configuration, defina o back-end de script como IL2CPP.
- O IL2CPP geralmente faz com que os builds sejam menores e tenham melhor desempenho.
- O IL2CPP também é a ÚNICA opção disponível no iOS. Selecioná-lo aqui permite que as duas plataformas tenham uma paridade melhor e simplifica as diferenças de depuração entre elas (se você optar por criar as duas).
- Crie o app. Em File > Build Settings, faça o seguinte:
- Verifique se a opção Create symbols.zip está marcada (ou, se houver um menu suspenso, selecione Debugging).
- Crie o APK diretamente no Editor do Unity na subpasta Builds/Android que você acabou de criar.
- Quando o build for concluído, você vai precisar gerar um arquivo de símbolo compatível com o Crashlytics e fazer upload dele para os servidores do Firebase. Essas informações de símbolos são necessárias para conferir stack traces simbolizados para falhas da biblioteca nativa no painel do Crashlytics.
Gere e faça upload desse arquivo de símbolos executando o seguinte comando da CLI do Firebase:firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
FIREBASE_APP_ID
: seu ID do app Android do Firebase (não o nome do pacote). Encontre esse valor no arquivogoogle-services.json
que você fez o download anteriormente. É o valormobilesdk_app_id
.
Exemplo de ID do app 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 o build foi concluído (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 conferir os dados iniciais no painel do Crashlytics no console do Firebase, é necessário forçar uma falha de teste.
- Na MainGameScene, encontre o EmptyObject
GameObject
na Hierarchy do editor, adicione o script abaixo a ele e salve a cena. Esse script causa uma falha no teste alguns segundos depois da execução do app.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");
}
}
} - Crie o app e faça upload das informações de símbolo após o término da criação.
- iOS: o plug-in do Editor do Firebase para Unity configura automaticamente seu projeto do Xcode para fazer upload do arquivo de símbolo.
- Android: execute o comando
crashlytics:symbols:upload
da CLI do Firebase para fazer upload do arquivo de símbolo.
- Execute o app. Quando ele estiver em execução, observe o registro do dispositivo e aguarde a exceção ser acionada pelo
CrashlyticsTester
.- iOS: veja os registros no painel inferior do Xcode.
- Android: confira os registros executando o comando
adb logcat
no terminal.
- Acesse o painel do Crashlytics para conferir a exceção. Ele aparece na tabela Issues na parte de baixo do painel. Mais adiante no codelab, você vai aprender a analisar esses relatórios.
- Depois de confirmar que o evento foi enviado ao Crashlytics, selecione o EmptyObject
GameObject
a que ele foi anexado, remova apenas o componenteCrashlyticsTester
e salve a cena para restaurar a condição original.
5. Ativar e entender 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ê vai criar um menu no projeto do Unity que vai demonstrar como usar a funcionalidade mais avançada do Crashlytics no jogo. O projeto do Unity Level Up with Firebase já tem um menu de depuração oculto que você vai tornar visível e escrever a funcionalidade.
Ativar o menu de depuração
O botão para acessar o menu de depuração existe no seu projeto do Unity, mas não está ativado no momento. É necessário ativar o botão para acessá-lo no prefab MainMenu
:
- No Unity Editor, abra o prefab chamado
MainMenu
. - Na hierarquia do prefab, encontre e selecione o subobjeto desativado chamado
DebugMenuButton
. - Ative o
DebugMenuButton
marcando a caixa no canto superior esquerdo à esquerda do campo de texto que contémDebugMenuButton
. - Salve o prefab.
- Execute o jogo no editor ou no dispositivo. O menu agora está acessível.
Visualizar e entender os corpos de método do menu de depuração
Mais adiante neste codelab, você vai escrever corpos de método para alguns métodos de depuração pré-configurados do Crashlytics. No projeto do Unity do Level Up with Firebase, no entanto, 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 erros gerados pela captura 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 Google Analytics para ajudar na depuração:
LogProgressEventWithStringLiterals
LogIntScoreWithBuiltInEventAndParams
Nas próximas etapas deste codelab, você vai implementar esses métodos e aprender como eles ajudam a resolver situações específicas que podem ocorrer no desenvolvimento de jogos.
6. Garantir o envio de relatórios de erros no desenvolvimento
Antes de começar a implementar esses métodos de depuração e conferir como eles afetam os relatórios de erros, entenda como os eventos são informados ao Crashlytics.
Para projetos do Unity, os eventos de falha e exceção no jogo são gravados imediatamente no disco. Para exceções não capturadas que não apresentam falhas no seu jogo (por exemplo, exceções não capturadas de C# na lógica do jogo), é possível fazer com que o SDK do Crashlytics relate esses dados como eventos fatais definindo a propriedade Crashlytics.ReportUncaughtExceptionsAsFatal
como true
ao inicializar o Crashlytics no seu projeto do Unity. Esses eventos são informados ao Crashlytics em tempo real sem que o usuário final precise reiniciar o jogo. As falhas nativas são sempre relatadas como eventos fatais e enviadas quando um usuário final reinicia o jogo.
Além disso, observe as seguintes diferenças pequenas, mas significativas, entre a forma como os diferentes ambientes de execução enviam informações do Crashlytics para o Firebase:
Simulador do iOS:
- As informações do Crashlytics só são informadas se você desconectar o Xcode do simulador. Se o Xcode estiver conectado, ele vai detectar os erros upstream, impedindo a entrega de informações.
Dispositivos físicos móveis (Android e iOS):
- Específico do Android: os ANRs são informados apenas no Android 11 e versões mais recentes. Os ANRs e eventos não fatais são informados na próxima execução.
Editor do Unity:
- As informações do Crashlytics do editor no modo de reprodução ou autônomo NÃO são gravadas nem enviadas para o Firebase. Além disso, o fluxo de trabalho de desenvolvimento do Firebase para computador não oferece suporte ao Crashlytics.
Testar o travamento do jogo ao tocar em um botão em CrashNow()
Depois que o Crashlytics é configurado no jogo, o SDK do Crashlytics registra automaticamente falhas e exceções não detectadas e as envia para o Firebase para análise. Os relatórios são exibidos no painel do Crashlytics no console do Firebase.
- Para demonstrar que isso é automático: abra
DebugMenu.cs
e substitua o métodoCrashNow()
da seguinte maneira:void CrashNow()
{
TestCrash();
} - Compile seu app.
- (Somente Android) Faça upload dos símbolos executando o seguinte comando da CLI do Firebase:
firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
- Toque no botão Crash Now e siga para a próxima etapa deste codelab para saber como conferir e interpretar o relatório de falha.
7. Entender os relatórios de problemas no Console do Firebase
Para conferir seus relatórios de falhas, você precisa saber um pouco mais sobre como aproveitar ao máximo. Cada um dos métodos que você escrever vai mostrar como adicionar diferentes tipos de informações aos relatórios do Crashlytics.
- Toque no botão Crash Now e reinicie o app.
- Acesse o painel do Crashlytics. Role a tela para baixo até a tabela Issues na parte de baixo do painel, em que o Crashlytics agrupa eventos que têm a mesma causa raiz em "issues".
- Clique no novo problema listado na tabela Issues. Ao fazer isso, o resumo do evento é exibido sobre cada evento individual enviado ao Firebase.
Você vai ver algo como a captura de tela a seguir. Observe como o resumo do evento mostra o stack trace da chamada que levou ao erro.
Metadados adicionais
Outra guia útil é a Unity Metadata. Esta seção informa sobre os atributos do dispositivo em que o evento ocorreu, incluindo recursos físicos, modelo/especificações da CPU e todos os tipos de métricas de GPU.
Confira um exemplo em que as informações nessa guia podem ser úteis:
imagine que seu jogo usa muitos shaders para alcançar um determinado visual, mas nem todos os smartphones têm GPUs capazes de renderizar esse recurso. As informações na guia Unity Metadata podem dar uma ideia melhor de qual hardware o app precisa testar ao decidir quais recursos disponibilizar automaticamente ou desativar totalmente.
Embora um bug ou falha nunca aconteça no seu dispositivo, devido à enorme diversidade de dispositivos Android em uso, é possível entender melhor os "pontos de acesso" específicos dos dispositivos do seu público-alvo.
8. Gerar, capturar e registrar uma exceção
Muitas vezes, como desenvolvedor, mesmo que seu código detecte e processe corretamente uma exceção de execução, é bom observar que ela ocorreu e em quais circunstâncias. O Crashlytics.LogException
pode ser usado para essa finalidade exata: enviar um evento de exceção ao Firebase para que você possa depurar o problema no console do Firebase.
- Em
Assets/Hamster/Scripts/States/DebugMenu.cs
, anexe o seguinte às instruçõesusing
:// Import Firebase
using Firebase.Crashlytics; - Ainda em
DebugMenu.cs
, substituaLogNonfatalError()
da seguinte maneira:void LogNonfatalError()
{
try
{
throw new System.Exception($"Test exception thrown in {nameof(LogNonfatalError)}");
}
catch(System.Exception exception)
{
Crashlytics.LogException(exception);
}
} - Compile seu app.
- (Somente Android) Faça upload dos símbolos executando o seguinte comando da CLI do Firebase:
firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
- Toque no botão Registrar erro não fatal e reinicie o app.
- Acesse o painel do Crashlytics. Você vai encontrar algo parecido com o que viu na última etapa deste codelab.
- No entanto, desta vez, restrinja o filtro Tipo de evento a Não fatais para que você só veja erros não fatais, como o que acabou de registrar.
9. Registrar 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 ou milhares de vezes por sessão, pode gerar uma exceção ou falha repentinamente? Pode ser bom analisar o código em um ambiente de desenvolvimento integrado e conferir os valores mais de perto, mas e se isso acontecer apenas entre uma porcentagem muito pequena dos seus usuários? Pior ainda, o que você faria se não conseguisse replicar esse erro, não importa o que fizesse?
Em situações como essa, ter algum contexto pode fazer toda a diferença. Com Crashlytics.Log
, você pode escrever o contexto necessário. Pense nessas mensagens como dicas para seu eu do futuro sobre o que pode estar acontecendo.
Embora os registros possam ser usados de várias maneiras, eles geralmente são mais úteis para registrar situações em que a ordem e/ou a ausência de chamadas é uma informação vital.
- Em
Assets/Hamster/Scripts/States/DebugMenu.cs
, substituaLogStringsAndCrashNow()
da seguinte maneira: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();
} - Compile seu app.
- (Somente Android) Faça upload dos símbolos executando o seguinte comando da CLI do Firebase:
firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
- Toque no botão Log Strings and Crash Now e reinicie o app.
- Volte ao painel do Crashlytics e clique no problema mais recente listado na tabela Issues. Novamente, você vai encontrar algo semelhante aos problemas anteriores.
- No entanto, se você clicar na guia Registros em um Resumo do evento, vai aparecer uma visualização como esta:
10. Gravar e substituir uma chave personalizada
Digamos que você queira entender melhor uma falha correspondente a variáveis definidas para um pequeno número de valores ou configurações. Talvez seja bom poder filtrar com base na combinação de variáveis e valores possíveis que você está analisando 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 programa quando ele falha: chaves personalizadas.
Esses são pares de chave-valor que podem ser definidos para uma sessão. Ao contrário dos registros, que se acumulam e são puramente aditivos, as chaves podem ser substituídas para refletir apenas o status mais recente de uma variável ou condição.
Além de ser um registro do último estado registrado do programa, essas chaves podem ser usadas como filtros poderosos para problemas do Crashlytics.
- Em
Assets/Hamster/Scripts/States/DebugMenu.cs
, substituaSetAndOverwriteCustomKeyThenCrash()
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();
} - Compile seu app.
- (Somente Android) Faça upload dos símbolos executando o seguinte comando da CLI do Firebase:
firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
- Toque no botão Set Custom Key and Crash e reinicie o app.
- Volte ao painel do Crashlytics e clique no problema mais recente listado na tabela Problemas. Novamente, você vai encontrar algo semelhante aos problemas anteriores.
- Dessa vez, clique na guia Chaves no Resumo do evento para conferir o valor das chaves, incluindo
Current Time
:
Por que usar chaves personalizadas em vez de registros personalizados?
- Os registros 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, é possível filtrar facilmente os problemas pelos valores das chaves na caixa de pesquisa da tabela Problemas.
No entanto, assim como os registros, as chaves personalizadas têm um limite. O Crashlytics é compatível com, no máximo, 64 pares de chave-valor. Ao atingir esse limite, os valores adicionais não serão salvos. Cada par de chave-valor pode ter um tamanho de até 1 KB.
11. (Somente no Android) Usar 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 O app não está respondendo (ANR). Os ANRs ocorrem quando um app não responde à entrada por mais de cinco segundos. Se isso acontecer, significa que o app travou ou está muito lento. Uma caixa de diálogo é mostrada aos usuários, e eles podem escolher entre "Aguardar" ou "Fechar o app".
Os ANRs são uma experiência ruim para o usuário e, como mencionado no link acima, podem afetar a possibilidade de descoberta do app na Google Play Store. Devido à complexidade e ao fato de serem frequentemente causadas por códigos multithread com comportamento muito diferente em diferentes modelos de smartphone, a reprodução de ANRs durante a depuração geralmente é muito difícil, quase impossível. Por isso, a melhor abordagem é geralmente a analítica e dedutiva.
Neste método, vamos usar uma combinação de Crashlytics.LogException
, Crashlytics.Log
e Crashlytics.SetCustomKey
para complementar o registro automático de problemas e fornecer mais informações.
- Em
Assets/Hamster/Scripts/States/DebugMenu.cs
, substituaSetLogsAndKeysBeforeANR()
da seguinte maneira: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);
} - Compile seu app.
- Faça upload dos símbolos executando o seguinte comando da CLI do Firebase:
firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
- Toque no botão Set Logs And Keys → ANR e reinicie o app.
- Volte para o painel do Crashlytics e clique no novo problema na tabela Problemas para conferir o Resumo do evento. Se a chamada foi feita corretamente, você verá algo como isto:
Como você pode ver, o Firebase identificou a espera ocupada na linha de execução como o principal motivo pelo qual o app acionou um ANR. - Se você analisar os registros na guia Registros do Resumo do evento, vai notar que o último método registrado como concluído é
DoSevereWork
.
Por outro lado, o último método listado como inicialização éDoExtremeWork
, o que indica que o ANR ocorreu durante esse método e o jogo foi fechado antes de registrarDoExtremeWork
.
Por que fazer isso?
- A reprodução de ANRs é muito difícil. Por isso, é muito importante ter informações detalhadas sobre a área do código e as métricas para descobrir o problema de forma dedutiva.
- Com as informações armazenadas nas chaves personalizadas, agora você sabe qual linha de execução assíncrona demorou mais para ser executada e quais estavam em risco de acionar ANRs. Esse tipo de dados lógicos e numéricos relacionados mostra onde é mais necessário otimizar o código.
12. Como intercalar eventos do Google Analytics para enriquecer ainda mais os relatórios
Os métodos a seguir também podem ser chamados no menu de depuração, mas, em vez de gerar problemas, eles usam o Google Analytics como outra fonte de informações para entender melhor o funcionamento do jogo.
Ao contrário dos outros métodos que você escreveu neste codelab, use esses métodos em combinação com os outros. Chame esses métodos (pressionando o botão correspondente no menu de depuração) na ordem que quiser antes de executar um dos outros. Em seguida, quando você examinar as informações no problema específico do Crashlytics, vai encontrar 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 o app.
- Em
Assets/Hamster/Scripts/States/DebugMenu.cs
, substitua as implementações atuais 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
);
} - Crie e implante seu jogo e entre no Menu de depuração.
- (Somente Android) Faça upload dos símbolos executando o seguinte comando da CLI do Firebase:
firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
- Pressione pelo menos um dos botões a seguir uma ou mais vezes para chamar as funções acima:
- Registrar evento de string
- Registrar evento de interrupção
- Pressione o botão Crash Now.
- Reinicie o jogo para que ele faça upload do evento de falha para o Firebase.
- Quando você registra várias sequências arbitrárias de eventos do Google Analytics e faz com que o jogo gere um evento que o Crashlytics usa para criar um relatório (como você acabou de fazer), elas são adicionadas à guia Registros do Resumo do evento do Crashlytics, como esta:
13. O futuro
Com isso, você terá uma base teórica melhor para complementar seus relatórios de erros gerados automaticamente. Com essas novas informações, você pode usar o estado atual, os registros de eventos anteriores e os eventos atuais do Google Analytics para detalhar melhor a sequência de eventos e a lógica que levou ao resultado.
Se o app for direcionado ao Android 11 (nível 30 da API) ou versões mais recentes, considere incorporar o GWP-ASan, um recurso de alocador de memória nativa ú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, ative explicitamente o GWP-ASan.
Próximas etapas
Acesse o codelab Instrumentar seu jogo do Unity com a Configuração remota para aprender a usar a Configuração remota e o teste A/B no Unity.