Personaliza los informes de fallas de Firebase Crashlytics

En esta guía, se describe cómo personalizar tus informes de fallas con las API de Crashlytics. De forma predeterminada, Crashlytics recopila informes de fallas por error de código nativo de la plataforma de todos los usuarios de tu app automáticamente (también puedes desactivar los informes de fallas automáticos y habilitar los informes de aceptación para tus usuarios en su lugar). Crashlytics proporciona cinco mecanismos de registro desde el primer momento: claves personalizadas, registros personalizados, identificadores de usuario, excepciones detectadas y no detectadas.

En el caso de las apps de Flutter, se envían informes de errores irrecuperables a Crashlytics en tiempo real sin necesidad de que el usuario reinicie la aplicación. Los informes de errores recuperables se escriben en el disco para enviarse junto con el próximo informe de errores irrecuperables o cuando se reinicia la app.

Informa excepciones no detectadas

Puedes detectar automáticamente todos los errores “irrecuperables” que se producen dentro del framework de Flutter anulando FlutterError.onError con FirebaseCrashlytics.instance.recordFlutterFatalError. Como alternativa, para detectar las excepciones “recuperables”, anula FlutterError.onError con 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());
}

Errores asíncronos

El framework de Flutter no detecta los errores asíncronos:

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

Para detectar esos errores, puedes usar el controlador 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());

}

Errores fuera de Flutter

Para detectar errores que ocurren fuera del contexto de Flutter, instala un objeto de escucha de errores en el Isolate actual:

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

Informa excepciones detectadas

Además de informar las fallas de la app automáticamente, Crashlytics te permite registrar excepciones recuperables y te las envía la próxima vez que se informe un evento irrecuperable o cuando se reinicie la app.

Usa el método recordError para registrar excepciones recuperables en los bloques catch de tu app. Por ejemplo:

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

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

También puedes registrar más información sobre el error si usas la propiedad information:

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

Estas excepciones aparecen como problemas recuperables en Firebase console. Este resumen de problemas contiene toda la información de estado que se obtiene normalmente a partir de las fallas, junto con desgloses por versión y dispositivo de hardware.

Crashlytics procesa las excepciones en un subproceso dedicado en segundo plano para minimizar el impacto en el rendimiento de tu app. Para reducir el tráfico de red de tus usuarios, Crashlytics limitará la cantidad de informes que se envían fuera del dispositivo, si es necesario.

Agrega claves personalizadas

Las claves personalizadas te ayudan a obtener el estado específico de la app hasta el momento de la falla. Puedes asociar pares clave-valor arbitrarios con tus informes de fallas y, luego, usar las claves personalizadas para buscar y filtrar informes de fallas en Firebase console.

  • En el panel de Crashlytics, puedes buscar problemas que coincidan con una clave personalizada.

  • Cuando revises un problema específico en la consola, podrás ver las claves personalizadas asociadas a cada evento (pestaña secundaria Claves) y filtrar los eventos por claves personalizadas (menú Filtrar en la parte superior de la página).

Usa el método de instancia setCustomKey para establecer pares clave-valor. Estos son algunos ejemplos:

// 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);

Agrega mensajes de registro personalizados

Para darte más contexto sobre los eventos que se produjeron antes de una falla, puedes agregar registros personalizados de Crashlytics a la app. Crashlytics asocia los registros con los datos de fallas y los hace visibles en Firebase console, en la pestaña Registros de Crashlytics.

Usa log para identificar problemas. Por ejemplo:

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

Configura identificadores de usuarios

Para diagnosticar un problema, resulta útil saber cuáles de tus usuarios sufrieron una falla. Crashlytics incluye una manera de identificar usuarios de forma anónima en los informes de fallas.

Para agregar los ID de usuario a tus informes, asigna a cada usuario un identificador único con el formato de un número de ID, un token o un valor de hash:

FirebaseCrashlytics.instance.setUserIdentifier("12345");

Si en algún momento necesitas borrar un identificador de usuario después de configurarlo, restablece el valor a una string en blanco. Borrar un identificador de usuario no quita los registros de Crashlytics existentes. Si necesitas borrar los registros asociados con un ID de usuario, comunícate con el equipo de asistencia de Firebase.

Habilita los informes de aceptación

Según la configuración predeterminada, Crashlytics recopila informes de fallas de todos los usuarios de la app automáticamente. Para permitir que los usuarios tengan más control sobre los datos que envían, puedes habilitar los informes opcionales si inhabilitas los informes automáticos y solo envías datos a Crashlytics cuando lo decidas en tu código:

  1. Desactiva la recopilación automática de forma nativa:

    Plataformas de Apple

    Agrega una clave nueva al archivo Info.plist:

    • Clave: FirebaseCrashlyticsCollectionEnabled
    • Valor: false

    Android

    En el bloque application del archivo AndroidManifest.xml, agrega una etiqueta meta-data para desactivar la recopilación automática:

    <meta-data
        android:name="firebase_crashlytics_collection_enabled"
        android:value="false" />
    
  2. Habilita la recopilación para usuarios específicos llamando a la anulación de recopilación de datos de Crashlytics durante el tiempo de ejecución.

    El valor de anulación persiste en todos los lanzamientos de tu app para que Crashlytics pueda recopilar informes automáticamente. Para inhabilitar los informes automáticos de fallas, pasa false como el valor de anulación. Cuando se configura en false, el valor nuevo no se aplica hasta la próxima ejecución de la app.

    FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
    

Administra los datos de Crash Insights

Crash Insights te ayuda a resolver problemas a través de la comparación de tus seguimientos de pila anonimizados con seguimientos de otras apps de Firebase y te permite saber si tu problema es parte de una tendencia mayor. En muchos casos, Crash Insights incluso proporciona recursos para ayudarte a depurar la falla.

Crash Insights usa datos de fallas globales para identificar las tendencias de estabilidad comunes. Si prefieres no compartir los datos de la app, puedes inhabilitar esta función en el menú Crash Insights ubicado en la parte superior de la lista de problemas de Crashlytics de Firebase console.