94 votes

Régler une minuterie pour une longue période de temps, c'est-à-dire plusieurs minutes

Je veux utiliser firebase auth avec react native pour Login y Signup mais j'ai obtenu une erreur jaune :

La définition d'une minuterie pour une longue période de temps, c'est-à-dire plusieurs minutes, pose un problème de performance et de correction sur Android, car elle maintient le module de minuterie éveillé, et les minuteries ne peuvent être appelées que lorsque l'application est au premier plan. Voir ( https://github.com/facebook/react-native/issues/12981 ) pour plus d'informations. (Saw setTimeout avec une durée de 111862ms)

Comment puis-je réparer ça ?
Je ne veux pas l'ignorer, je veux comprendre cette erreur et la résoudre de la meilleure façon possible.
Et voici mon code :

  export default class Login extends Component {
        constructor(props) {
            super(props)
            this.state = {
                email: '',
                password: '',
                response: ''
            }
            this.signUp = this.signUp.bind(this)
            this.login = this.login.bind(this)
        }
        async signUp() {
            try {
                await firebase.auth().createUserWithEmailAndPassword(this.state.email, this.state.password)
                this.setState({
                    response: 'Account Created!'
                })
                setTimeout(() => {
                    this.props.navigator.push({
                        id: 'App'
                    })
                }, 1500)
            } catch (error) {
                this.setState({
                    response: error.toString()
                })
            }
        }
        async login() {
            try {
                await firebase.auth().createUserWithEmailAndPassword(this.state.email, this.state.password)
                this.setState({
                    response: 'user login in'
                })
                setTimeout(() => {
                    this.props.navigator.push({
                        id: 'App'
                    })
                })

            } catch (error) {
                this.setState({
                    response: error.toString()
                })
            }

        }
        render() {
            return (
                <View style={styles.container}>
                    <View style={styles.containerInputes}>
                        <TextInput
                            placeholderTextColor="gray"
                            placeholder="Email"
                            style={styles.inputText}
                          //  onChangeText={(email) => this.setState({ email })}
                            onChangeText={(email) => {console.log(email);}}
                        />
                        <TextInput
                            placeholderTextColor="gray"
                            placeholder="Password"
                            style={styles.inputText}
                            password={true}
                            onChangeText={(password) => this.setState({ password })}
                        />
                    </View>
                    <TouchableHighlight
                        onPress={this.login}
                        style={[styles.loginButton, styles.button]}
                    >
                        <Text
                            style={styles.textButton}
                        >Login</Text>
                    </TouchableHighlight>
                    <TouchableHighlight
                        onPress={this.signUp}
                        style={[styles.loginButton, styles.button]}
                    >
                        <Text
                            style={styles.textButton}
                        >Signup</Text>
                    </TouchableHighlight>
                </View>
            )
        }
    }

J'ai fait rapport à L'équipe Google Firebase : ( https://github.com/firebase/firebase-js-sdk/issues/97 )

27voto

Jam Risser Points 601

Vieux

Cela corrige la boîte jaune et le journal de la console. Elle le corrige même pour l'Expo.

Il suffit de placer le script suivant au début de votre codebase.

import { YellowBox } from 'react-native';
import _ from 'lodash';

YellowBox.ignoreWarnings(['Setting a timer']);
const _console = _.clone(console);
console.warn = message => {
if (message.indexOf('Setting a timer') <= -1) {
   _console.warn(message);
   }
};

Nouveau

YellowBox est déprécié et est remplacé par LogBox

import { LogBox } from 'react-native';
import _ from 'lodash';

LogBox.ignoreLogs(['Warning:...']); // ignore specific logs
LogBox.ignoreAllLogs(); // ignore all logs
const _console = _.clone(console);
console.warn = message => {
if (message.indexOf('Setting a timer') <= -1) {
   _console.warn(message);
   }
};

0 votes

Pour la console, cela devrait fonctionner : console.ignoredYellowBox = ['Setting a timer'];

2 votes

Des alternatives sans lodash ?

0 votes

Il faut absolument le cloner. Il existe de nombreuses façons de cloner des objets. Si vous utilisez ES6, la logique suivante est équivalente const _console = { ...console }; .

25voto

Sedric Heidarizarei Points 1144

Josh Crowther Ingénieur logiciel chez Google Said :

L'utilisation de setTimeouts de courte durée en plusieurs étapes ne résout pas vraiment le problème. Le module Timer reste toujours actif et l'application est toujours sujette aux problèmes de performance indiqués dans l'avertissement. Le problème ici est que nous avons des cas d'utilisation qui nécessitent des temporisations longues, et react-native n'est pas optimisé pour ce cas d'utilisation.

Donc le résultat de tout cela est : Ce bogue ne peut pas être corrigé ici, nous ne pouvons que contourner l'erreur ; il existe des solutions de contournement (cf. Régler une minuterie pour une longue période de temps, c'est-à-dire plusieurs minutes ) qui désactivent l'avertissement. Faire le travail pour désactiver l'avertissement dans notre code n'aide pas le problème (au-delà de la désactivation de l'avertissement), et ajoute du code/poids SDK supplémentaire qui est complètement inutile.

Je vous recommande d'intervenir sur la question mentionnée ci-dessus (c'est à dire facebook/react-native#12981 ) si vous n'êtes pas à l'aise avec la solution de contournement fournie.

3voto

Alex Nguyen Points 147

J'ai eu le même problème et je pense que c'est un problème de firebase web SDK donc j'ai décidé d'abandonner firebase web SDK parce qu'il fonctionne dans le thread js, pas le thread react-native.

Et j'ai trouvé react-native-firebase . C'est mieux que firebase web SDK avec des performances plus élevées et ce problème a disparu.

4 votes

Avez-vous vérifié le code source de cette librairie ? L'avertissement n'est pas affiché car l'auteur a utilisé l'astuce mentionnée ci-dessus :D github.com/invertase/react-native-firebase/

0 votes

@Sephy : Je n'ai pas encore vérifié le code source de la librairie, mais je l'utilise pour mon application et cela fonctionne bien.Et je n'ai pas non plus fait le tour que vous avez trouvé.

4 votes

Certaines personnes ont besoin d'utiliser le javascript firebase avec React Native, par exemple, Expo ne supporte pas react-native-firebase.

1voto

Jam Risser Points 601

Une autre approche consiste à utiliser le module react-native-ignore-warnings.

https://github.com/jamrizzi/react-native-ignore-warnings

https://www.npmjs.com/package/react-native-ignore-warnings

Cela fonctionne même pour les applications de l'Expo.

Vous l'utiliserez de la manière suivante

import ignoreWarnings from 'react-native-ignore-warnings';

ignoreWarnings('Setting a timer');

peut fonctionner avec Android aussi ?

7 votes

Bon Dieu, pourquoi cela existe-t-il ? !

2 votes

Eh bien spécifiquement pour ignorer les inévitables avertissements de firebase dans expo qui encombrent les journaux et rendent difficile le débogage de l'application.

0 votes

Dans quel dossier cela doit-il aller ?

1voto

Dave Meehan Points 36

En login() , votre setTimeout() Il manque une valeur d'intervalle à l'appel. En règle générale, les navigateurs ne déclenchent plus de délais/intervalles si la fenêtre/l'onglet est en arrière-plan, ou du moins on ne s'attend pas à ce qu'ils soient opportuns. Cela permet d'éviter les comportements abusifs de script, et de réduire la consommation d'énergie des scripts qui peuvent être en train de polluer.

Votre code devrait fonctionner en principe, si l'utilisateur s'éloigne de la fenêtre pendant que la minuterie est en cours, elle se terminera à son retour. C'est probablement ce que vous souhaitez d'un point de vue UX, car l'utilisateur voit la transition, plutôt qu'elle ne se produise en arrière-plan lorsqu'il ne regarde pas. Cela les aide à maintenir le contexte mental.

La boîte jaune est due au fait que vous définissez une minuterie excessivement longue selon le message (près de deux minutes) et qu'il est peu probable que cela corresponde au contexte que vous souhaitez. L'environnement JS vous avertit que ce que vous faites n'est probablement pas ce que vous voulez. Vous pouvez désactiver cet avertissement si c'est ce que vous voulez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X