长时间设置计时器,即多分钟

Sed*_*rei 46 javascript firebase react-native

我想使用firebase auth with native for Login,Signup但是我得到了一个黄色错误:

长时间(即多分钟)设置计时器是Android上的性能和正确性问题,因为它使计时器模块保持唤醒状态,并且只有在应用程序位于前台时才能调用计时器.有关详细信息,请参阅(https://github.com/facebook/react-native/issues/12981).(看到setTimeout,持续时间为111862ms)

我该如何解决这个问题?
我不想忽视这一点,我想理解这个错误并用最好的标准方式解决这个问题.
这是我的代码:

  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>
            )
        }
    }
Run Code Online (Sandbox Code Playgroud)

我向Google Firebase小组报告:(https://github.com/firebase/firebase-js-sdk/issues/97)

CLU*_*HER 42

要解决此问题...

  1. 导航到您的 node_modules/react-native/Libraries/Core/Timers/JSTimers.js 文件。

  2. 查找变量 MAX_TIMER_DURATION_MS

  3. 将其值更改为 10000 * 1000

  4. 保存更改(关闭自动格式)并重新构建您的应用程序。

https://github.com/firebase/firebase-js-sdk/issues/97#issuecomment-485410026上找到了这个答案

  • 这只是一个临时修复,因为当您更改“node_modules”文件时,它仅在您的本地环境中。因为你不应该提交node_modules。因此,每当新开发人员设置项目时,您都必须重新进行。这最终不是问题。这只是一个警告,Firebase 开发人员已经提到他们不会更改它,因为他们希望开发人员知道他们的库使用了与计时器相关的实现。– (2认同)

小智 19

只需添加这两行

import { LogBox } from 'react-native';

LogBox.ignoreLogs(['Setting a timer']);
Run Code Online (Sandbox Code Playgroud)

  • 这应该是推荐的答案,因为其他解决方案已被弃用。 (3认同)
  • 忽略日志实际上并不能解决真正的问题。 (2认同)

Jam*_*ser 12

这样可以修复黄色框和控制台日志。它甚至为Expo修复了它。

只需将以下脚本放在代码库的开头。

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);
  }
};
Run Code Online (Sandbox Code Playgroud)

  • 没有lodash的任何替代品? (2认同)

Sed*_*rei 9

Google Say的Josh Crowther软件工程师:

使用多步短持续时间setTimeouts实际上并不能解决问题.定时器模块仍然保持活动状态,应用程序仍然会受到警告中指示的性能问题的影响.这里的问题是,我们有需要长计时器的用例,而本机的react-native不会针对该用例进行优化.

因此,所有这一切的网络:此错误无法修复,我们只能解决错误,有可用的解决方法(请参阅设置长时间的计时器,即多分钟),以禁用警告.在我们的代码中执行禁用警告的工作并没有帮助解决问题(除了禁用警告之外),并添加了完全没有必要的额外SDK代码/权重.

如果你不舒服,我建议你在上面提到的问题上讨论(例如facebook/react-native#12981)


Cri*_*ani 6

解决黄色警告“设置计时器”的问题。

复制并导入以下文件(尽可能快;-))

import {Platform, InteractionManager} from 'react-native';

const _setTimeout = global.setTimeout;
const _clearTimeout = global.clearTimeout;
const MAX_TIMER_DURATION_MS = 60 * 1000;
if (Platform.OS === 'android') {
    // Work around issue `Setting a timer for long time`
    // see: https://github.com/firebase/firebase-js-sdk/issues/97
    const timerFix = {};
    const runTask = (id, fn, ttl, args) => {
        const waitingTime = ttl - Date.now();
        if (waitingTime <= 1) {
            InteractionManager.runAfterInteractions(() => {
                if (!timerFix[id]) {
                    return;
                }
                delete timerFix[id];
                fn(...args);
            });
            return;
        }

        const afterTime = Math.min(waitingTime, MAX_TIMER_DURATION_MS);
        timerFix[id] = _setTimeout(() => runTask(id, fn, ttl, args), afterTime);
    };

    global.setTimeout = (fn, time, ...args) => {
        if (MAX_TIMER_DURATION_MS < time) {
            const ttl = Date.now() + time;
            const id = '_lt_' + Object.keys(timerFix).length;
            runTask(id, fn, ttl, args);
            return id;
        }
        return _setTimeout(fn, time, ...args);
    };

    global.clearTimeout = id => {
        if (typeof id === 'string' && id.startsWith('_lt_')) {
            _clearTimeout(timerFix[id]);
            delete timerFix[id];
            return;
        }
        _clearTimeout(id);
    };
}
Run Code Online (Sandbox Code Playgroud)


Kam*_*ain 5

如果您使用的是 react-native,0.63请在您的App.js文件中执行以下操作:LogBox从 react-native导入

import { LogBox } from 'react-native';
Run Code Online (Sandbox Code Playgroud)

并且在App.js文件中的所有导入之后只添加这一行,没有必要在任何 useEffect 调用中添加这一行。

LogBox.ignoreLogs(['Setting a timer for a long period of time'])
Run Code Online (Sandbox Code Playgroud)

查看文档以了解更多信息。

或者


如果您使用的是 react-native,0.62请在您的App.js文件中执行以下操作:YellowBox从 react-native导入

import { YellowBox } from 'react-native';
Run Code Online (Sandbox Code Playgroud)

并且在App.js文件中的所有导入之后只添加这一行,没有必要在任何 useEffect 调用中添加这一行。

YellowBox.ignoreWarnings(['Setting a timer for a long period of time']);
Run Code Online (Sandbox Code Playgroud)

查看文档以了解更多信息。