AdamG
AdamG

Reputation: 2630

React Native Warning: "Setting a timer for a long period of time...". How to locate cause?

Everything on iOS works fine. On Android I am getting the warning "Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 589668ms)"

I don't use any timers in my app so I am assuming this is from an NPM module I have installed. How can I determine which one is causing this?

I see that I can ignore the waring, but I would like to report the issue to the module maintainer.

Upvotes: 1

Views: 16465

Answers (4)

Philipp Sumi
Philipp Sumi

Reputation: 987

For firebase/firestore users: I simply reverted to using the REST endpoints directly for firestore calls rather than trying to mask the warning. Since I only needed auth and firestore, that solved my problems rather easily. Snippet here:

https://stackoverflow.com/a/62446792

Upvotes: 1

Vishesh_Malhotra
Vishesh_Malhotra

Reputation: 63

This link will help you https://github.com/facebook/react-native/issues/12981#issuecomment-499827072

The code (from here: firebase/firebase-js-sdk#97 (comment)) simply wraps the setTimeout (global) function to prevent it from being used with a long period.

In our modified global.setTimeout function, if the duration time is greater than the threshold MAX_TIMER_DURATION_MS, we save an id in a local map (timerFix) and then call runTask which splits the duration time into smaller values. runTask sets a timeout (using the original _setTimeout) with the smaller chunks that will be continuously executed until waitingTime is too small. When waitingTime is small enough, we call React Native's runAfterInteractions for a smooth execution, and, at the same time, we remove the id entry from our local map because we won't be calling _setTimeout again in this case. Note that afterTime is fed into _setTimeout to prevent it from being called with a long period.

Otherwise, in our modified global.setTimeout function, if the duration time is smaller than the threshold MAX_TIMER_DURATION_MS, we directly call the global setTimeout (saved in _setTimeout).

The global clearTimeout is also wrapped to perform a cleanup process by removing the id from the local map.

Upvotes: 1

Bai Nguyen
Bai Nguyen

Reputation: 834

The https://github.com/facebook/react-native/issues/12981 said you need edit server file. In you index.js file

var server = require('https').Server(options, app);
var io = require('socket.io')(server);

change to

var server = require('https').Server(options, app);
var io = require('socket.io')(server,{pingTimeout: 30000});

and then run forever restartall to restart

Upvotes: 1

Cobolt
Cobolt

Reputation: 952

This is a warning that certain javascript dependencies will raise on react-native due to an issue on their side and must be solved in react-native's codebase but is not a cause for concern. If it bothers you just add console.ignoredYellowBox = ['Setting a timer'];. To find out which dependency is causing it you must debug the app with chrome and ensure sourcemaps are enabled.

Upvotes: 7

Related Questions