React Native

,

Firebase

Optimisez votre application avec Firebase Crashlytics

Intégrer crashlytics de firebase à votre application React Native.

Murat

Murat

09 décembre 2021

Optimisez votre application avec Firebase Crashlytics

Le “crash reporting” vous connaissez ? C’est une des notions les plus importantes afin d’assurer la bonne qualité de votre application.

Les bugs et crashes qui appairaissent dans votre application une fois déployée, peuvent être très difficile à taquer. Vous ne serez sûrement pas en contact avec les utilisateurs afins qu’ils puissent vous détailler ce qu’il s’est passé. Et encore pire, l’utilisateur vous laissera sûrement une mauvaise note.

Dans ce tutoriel, nous allons voir comment intégrer le module crashlytics à votre applicatin react native.

Ce tutoriel nécessite que vous ayez complété notre première partie sur l’initialisation de firebase avec React Native.

Installation

Le module @react-native-firebase/crashlytics propose des fonctionnalités utiles pour les développeurs.

Créer le projet dans la console Firebase

Allez sur la console Firebase, assurez-vous que votre projet est créé, sinon suivez l’article précédent.

Intégrer @react-native-firebase/crashlytics

Exécutez dans un terminal dans votre projet :

yarn add @react-native-firebase/crashlytics
cd ios/ && pod install

Pour la partie android, dans android/build.gradle :

// ..
buildscript {
// ..
dependencies {
// ..
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
}
// ..
}

Puis build à nouveau le projet avec :

npx react-native run-android

Tester votre configuration

Afin d’être sûr que le paramétrage fonctionne, créez d’abord un fichier firebase.json à la racine de votre projet, en y ajoutant :

{
"react-native": {
"crashlytics_auto_collection_enabled": true,
"crashlytics_debug_enabled": true, // c'est temporaire, on va remettre à false plus tard
"crashlytics_javascript_exception_handler_chaining_enabled": false
}
}

crashlytics_debug_enabled permet de dire à Crashlytics d’également tracker les bugs en mode debug. C’est important pour notre premier test.

Ensuite, soit lors d’un clic de bouton, soit au chargement d’un screen, insérez ce bout de code :

import crashlytics from '@react-native-firebase/crashlytics';
// ..
crashlytics().crash();

Allez ensuite sur la console Firebase, puis attendez 1 ou 2 minutes pour voir apparaître votre erreur :

Testez la manip’ sur les 2 simulateurs iOS et android pour être sûr que tout fonctionne.

Maintenant, on peut passer aux cas pratiques !

Intégration d’un ErrorBoundary

Explication

Crashlytics va maintenant attraper les erreurs qui proviennent dans votre application, et vous les lister dans la console. Mais comme vous le savez, le code react native est compilé en natif, donc vous perdez votre code javascript lors de la release.

Donc vos stack d’erreurs ne seront pas très lisible.

Exemple de stack d’erreur reporté par crashlytics.

Fatal Exception: java.lang.ClassCastException: com.facebook.react.bridge.ReadableNativeMap cannot be cast to java.lang.String
at com.facebook.react.bridge.ReadableNativeArray.getString(ReadableNativeArray.java:102)
at com.facebook.react.bridge.JavaMethodWrapper$5.extractArgument(JavaMethodWrapper.java:73)
at com.facebook.react.bridge.JavaMethodWrapper$5.extractArgument(JavaMethodWrapper.java:69)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:356)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
at com.facebook.react.bridge.queue.NativeRunnable.run(NativeRunnable.java)

La méthode pour récupérer l’erreur javascript est la suivante :

crashlytics().recordError(error);

ErrorBoundary

L’explication étant maintenant terminée, passons à la bonne pratique. Le composant ErrorBoundary permet de rattraper les erreurs qui se produisent dans le code javascript, et de montrer une vue plus propre à l’utilisateur, au lieu de faire cracher l’application.

Comme par exemple :

Nous allons mettre en place ce composant, et envoyer les erreurs à Crashlytics à ce moment.

Dans component/ErrorBoundary.js :

import crashlytics from '@react-native-firebase/crashlytics';
import { node } from 'prop-types';
import React, { Component } from 'react';
import { SafeAreaView, Text, View } from 'react-native';
import RNRestart from 'react-native-restart'
import Button from '~/components/common/Button';
import t from '~/configs/i18n';
import styles from './styles';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {};
}
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
if(errorInfo && errorInfo.componentStack) {
crashlytics().log(errorInfo.componentStack);
}
crashlytics().recordError(error, error.message ? error.message : undefined);
}
onRestart() {
RNRestart.Restart();
};
render() {
const { hasError } = this.state;
const { children } = this.props;
if (hasError) {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<View style={styles.content}>
<Text style={{ width: '100%', }}>
500
</Text>
<Text style={{ fontSize: 32 }}>{t('label.error')}</Text>
<Text style={{ marginVertical: 10, lineHeight: 23, fontWeight: '500' }}>
{t('error.description')}
</Text>
<Button
onPress={() => this.onRestart()}
>
{t('action.backToLogin')}
</Button>
</View>
</View>
</SafeAreaView>
);
}
return children;
}
}
ErrorBoundary.propTypes = {
children: node,
};
ErrorBoundary.defaultProps = {
children: null,
};
export default ErrorBoundary;

Puis dans App.js, entourez votre application avec ce composant :

return (
<ErrorBoundary>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
{storybookActive ? <StorybookUIRoot /> : <Router />}
</PersistGate>
</Provider>
</ErrorBoundary>
);

Voila ! Maintenant à chaque crash, nous allons envoyer les informations js à la console Crashlytics de Firebase. Ce que j’aime bien mettre en place, c’est le rechargement de l’application lors du clic sur le bouton, grâce à la dépendance react-native-restart. C’est optionnel bien sûr.

Loggez encore plus d’information

Grâce à l’étape précédente, vous aurez la stacktrace javascript. Mais c’est toujours mieux de rajouter plus d’info (bien sûr, avec parcimonie).

Pour cela 2 méthodes :

crashlytics().log(errorInfo.componentStack); //celle-là permet de logger une activité sur crashlytics
crashlytics().setAttribute(attribute, value); //celle-là permet de mettre un attribut

J’utilise la 2ème méthode pour savoir sur quelle page l’utilisateur se trouvait avant le grand crash.

Si vous utilisez @react-navigation/native :

<NavigationContainer
theme={AppTheme}
ref={navigationRef}
onReady={() => {
routeNameRef.current = navigationRef.current.getCurrentRoute().name;
crashlytics().setAttribute("screen", routeNameRef.current);
}}
onStateChange={() => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current.getCurrentRoute().name;
if (previousRouteName !== currentRouteName) {
crashlytics().setAttribute("screen", currentRouteName);
}
routeNameRef.current = currentRouteName;
}}
>

Conclusion

Et voila ! Ça fait pas mal d’information quand même. Maintenant j’espère que vous allez pouvoir débugger vos applications plus facilement. Ne tracker pas des informations susceptibles d’identifier vos utilisateurs (#rgpd).

Technologies dans cet article ...

Mobile

React Native

React Native

Firebase

Firebase

D'autres articles dans la même catégorie...

Stéphane

#Javascript

#Cordova

#React Native

#HTML

#Développement

#Application mobile

Développement mobile : Natif vs. hybride.

Lorsqu'il s'agit de développer une application mobile, l'une des premières décisions à prendre est de choisir entre le développement natif et le développement hybride. Chaque approche a ses avantages et ses inconvénients, et le choix dépendra de nombreux facteurs, tels que votre budget, vos objectifs et vos attentes. Dans cet article, nous allons comparer le développement d'applications natives et hybrides, afin de vous aider à déterminer quelle approche est la meilleure pour votre application spécifique.

Stéphane

Stéphane

28 décembre 2023

Farid

#Android Natif

#React Native

#Firebase

#Cordova

#Application mobile

#Développement

Bonnes pratiques pour le développement d'apps mobiles

Le développement d'applications mobiles est un domaine en constante évolution, avec de nouvelles technologies et approches émergentes chaque jour. Pour rester compétitif et créer des applications qui répondent aux attentes des utilisateurs, il est essentiel de suivre les meilleures pratiques de l'industrie. Dans cet article, nous allons explorer les meilleures pratiques pour le développement d'applications mobiles qui peuvent aider à garantir le succès de votre application.

Farid

Farid

11 avril 2023

Murat

#React Native

#Firebase

Comment déployer des apps iOS avec Apple Ad-Hoc

Vous souhaitez vous concentrez sur le développement de votre application, vous êtes pas prêt pour la validation d'Apple, mais vous souhaitez faire tester votre application ? Apple Ad-hoc est là pour vous.

Murat

Murat

03 avril 2023