react-native-background-timer
react-native-background-timer copied to clipboard
working for only 30 seconds on the background for iOS
its working for only 30 seconds on the background for iOS... on android no issues
how to fix it?
Try to use 15 minutes, if I am not mistaken the IOS has a minimum 15 minute interval. Otherwise, the system drops its tasks.
@raulcrash what do you mean by saying 15 minutes?
do you mean doing that:
BackgroundTimer.runBackgroundTimer(() => { console.log("hey") }, 900000);
900000 ms=15 minutes?
have you try that?
Yes. Did it work for you?
No it didn’t
On 6 May 2020, at 16:53, raulcrash [email protected] wrote:
Yes. Did it work for you?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.
you are talking about two different things. the 15 minute interval is for Background Fetch, and it's the minimum time you can request for the OS to spin up your application and perform a background fetch if enabled by the user. This is also opportunistic, and will not run at a consistent interval, but rather when the system has extra resources and spare CPU time, etc, and can be batched with other apps during background fetches.
The reason the application is suspending at 30 seconds is because in the implementation for this code you are still using the DispatchQueue.mainQueue, which is most likely mapping to the main thread (they are different things) which when the application is in the background, it is suspended. The suspension is not always 30 seconds, but rather can be determined by the system and its performance mode. If they are in the low battery mode, it might be shorted, or lengthened out it the CPU is throttled on older devices. The only way you are able to maintain something in the background is by starting the background task, then doing that task on a background queue, and then completing correctly ending that task, to extend beyond that background thread, but you must have started the registered task before you were moved into the background. You cannot use it to keep the application on indefinitely. You can ask for an extension on the time, but you may not receive it. The purpose is not to run a timer, but rather finish a critical process before you thread is suspended, like a file io write, a network request, or a database write. It best practice to initiate the background task, keep that pointer, do the time intensive operation, like file IO and then compete the task. you are saying, hey, i may need to run longer, i will let you know when i'm done, and when done, you state your done, and it will give to a bit longer than the normal time, but not on the main thread, rather a background thread (you should not do file I/O or network requests on the main thread, and most top level async libraries already do this.
By virtue of how react native works, the JS thread (which is not main thread) will call down to the Native module on a different thread (unless you specify you need main thread, which unless you are doing UI in a component updates, or accessing UIView UIKit apis, you should not). otherwise you are using a non main thread background thread managed through gcd. you can schedule on the background thread by doing a GCD dispatch to the background qos. When this code on ios is scheduling in the future using gcd on the main queue, it is going to most likely run on the main thread, so depending on the interval, it will inject an async block operation on the main thread that would also be alongside any UI animation. when it runs that it going to emit an event back into the JS environment on the JS thread to be handled by a react listener. So this code is doing a lot of thread hoping. Since the main thread is being suspended, and your task is schedule most likely on that thread, you are being suspended at 30 seconds.
@robertbarclay thank you for a very detailed explanation. I am working on an app and it requires some background functionality and this is really important in our case (Reason: we need to call an API every 1-3 minutes just to let the server know the user is logged in; otherwise the server will kill user session. It is not the best way to handle it but it is a third party server and we have no way to control the server functionality.).
As of your knowledge what you recommend to keep the application alive in background to run just for few milliseconds to call API after every 1-3 minutes? remember it is not long processing a very quick short API call and read the response and schedule the next call after a minute or so.
If you can please provide some help with this I will really appreciate it.
Thanks
Does anyone found solution for this
Also facing that issue. Once the app was moved to BG, approximately after 30 seconds the callback stops from being triggered.
same issue here +1
@ocetnik Do you have any idea why this is happening? Please help us to resolve this issue Thanks
I'm facing the same issue, after around 15 seconds it stops working! Any advice, please?
The same problem!
Same issue timer is paused after 30 secs in iOS when in background and continues again from there when in foreground. Any soln available???
same issue, any update on this?
Anybody with solution?? I also put question On Stackoverflow.
Any solution for this problem?
Hi @HyopeR If you want to use the background service to get user location, I'll advise you to go with Expo https://docs.expo.io/versions/latest/sdk/location/
+1, why we don't have solution and close this?
Lot of frontend sessional lazy coders