react-native-background-timer icon indicating copy to clipboard operation
react-native-background-timer copied to clipboard

BackgroundTimer stops when app goes to background after Few Sec in IOS React Native IOS

Open Omrbhatti opened this issue 3 years ago • 18 comments

Omrbhatti avatar Feb 09 '22 10:02 Omrbhatti

same issue in any method

DCaiena avatar Feb 14 '22 01:02 DCaiena

Same issue in android too😭

cw0516 avatar Mar 06 '22 09:03 cw0516

any updates?

alicja-mruk avatar Apr 07 '22 14:04 alicja-mruk

Any updates on this issue?

bwoodlt avatar Apr 22 '22 09:04 bwoodlt

This is still an issue, any updates?

marsieCohen avatar Jul 05 '22 14:07 marsieCohen

yes...same issue! any solution?

kaushikipandey avatar Jul 25 '22 17:07 kaushikipandey

same, ios

Simoon-F avatar Aug 05 '22 04:08 Simoon-F

any solution?

TranLuongTuanAnh avatar Aug 17 '22 08:08 TranLuongTuanAnh

same here using rn-0.67 tested on xaomi redmi note 7

mirsahib avatar Aug 17 '22 14:08 mirsahib

You dont need this library. You can achieve the same thing with Date, AppState and the built in setInterval.

rgcjhn avatar Aug 29 '22 23:08 rgcjhn

Same issue for me - is there an alternative library anyone can recommend?

jamesdmurphy51 avatar Aug 30 '22 03:08 jamesdmurphy51

no solution, IOS KILL ALL BACKGROUND METHOD after 30 seconds

fukemy avatar Sep 23 '22 08:09 fukemy

Although this defeat the purpose of using this library The closest thing is restart and calculate the timer by comparing the difference of a locally stored start time and current time when it the app comes back to the foreground.

vmia159 avatar Nov 30 '22 09:11 vmia159

You dont need this library. You can achieve the same thing with Date, AppState and the built in setInterval.

Could you provide some showcase code?

Aaronphy avatar Jan 09 '23 09:01 Aaronphy

@Aaronphy check this and maybe customized it because this was an old code

const HandlerComponent = () => {
  const lastKnownTime = useRef();
  const subscription = useRef();
  const appState = useRef(AppState.currentState);

  useEffect(() => {
    lastKnownTime.current = moment().format('x');
    subscription.current = AppState.addEventListener('change', nextAppState => {
      const isForeground =
        appState.current.match(/inactive|background/) &&
        nextAppState === 'active';

      if (isForeground) {
        const duration = getDuration(lastKnownTime.current); // <- duration while in background in seconds
      } else {
        lastKnownTime.current = moment().format('x');
      }
    });
    return () => subscription.current?.remove();
  }, []);

  const getDuration = unix => {
    return Math.floor(
      moment.duration(moment().diff(moment(unix, 'x'))).asSeconds(),
    );
  };

  return <></>;
};

rgcjhn avatar Feb 14 '23 01:02 rgcjhn

This is for timer purpose only and cannot do stuff

If you want to prevent someone that want trick your system, you can create a package to bridge native system uptime and use that instead of js moment/Date.

  1. When you start the timer, record the system uptime & boot time (current - uptime) when start.
  2. Use JS interval to get native system uptime.
  3. Save the current elapsed time by calculate the difference between current uptime and start uptime.
  4. In case someone change the clock manually. When the boot time is not the same, just pause the timer and show the last saved result.

For android

SystemClock.elapsedRealtime();

For IOS

#include <sys/sysctl.h>

- (time_t)uptime
{
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);
    time_t now;
    time_t uptime = -1;

    (void)time(&now);

    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) {
        uptime = now - boottime.tv_sec;
    }

    return uptime;
}

vmia159 avatar Apr 06 '23 09:04 vmia159

Same issue any solution Please?

Qurat-ul-ainn avatar Apr 02 '24 10:04 Qurat-ul-ainn

i am resolve this case to write the native swift code and call this code in react native code , and this work fine me app still working in background

@objc func startTimer(_ value: NSNumber) { print("Starting Timer with name: (value)")

    // Capture self weakly to avoid retain cycles
       timer = Timer.publish(every: TimeInterval(truncating: value), on: .main, in: .common)
        .autoconnect()
        .sink { [weak self] _ in
            guard let self = self else { return }
            print("Timer fired!")
            let onIncrement = "onIncrement"
            self.sendEvent(withName: onIncrement, body: ["message": "Timer fired with name \(value)!"])
            self.timerMessage = "Timer fired at \(Date())"
        }
}

omerabdelhadyy avatar Jul 20 '24 12:07 omerabdelhadyy