Ionic: setInterval/setTimer not functioning after 5 minutes in the background

In need of a timer that can send notifications via the OneSignal API after a user-defined time period is reached. Users can set the timer for any value between 1-59 minutes. Despite attempts to use the background mode plugin, specifically setInterval and setTimeout functions beyond 5 minutes seem to be problematic.

One approach involved using recursive setTimeout method:

function startTimerCounter() {
  this.timerCounter = 0;
  const objThis = this; //store this.

  if (this.timerCounter >= this.setTime) {
    this.backgroundMode.disable();
    this.goalTimerReached = true;
  } else {
    this.backgroundMode.enable();
    this.timer = setTimeout(function request() {
      if (objThis.timerCounter === objThis.setTime) {
        //onesignal notification
        clearTimeout(objThis.timer);
      } else {
        ++objThis.timerCounter;
        objThis.timer = setTimeout(request, 1000);
      }
    }, 1000);
  }
}

An alternative attempt utilized the setInterval method:

function startTimerCounter() {
  this.timerCounter = 0;
  const objThis = this; //store this.

  if (this.timerCounter >= this.setTime) {
    this.backgroundMode.disable();
    this.goalTimerReached = true;
  } else {
    this.backgroundMode.enable();
    this.timerCounter = 0;
    const objThis = this; //store this.
    this.timer = setInterval(() => {
      if (objThis.timerCounter === objThis.setTime) {
        //onesignal notification
        clearInterval(objThis.timer);
      } else {
        ++objThis.timerCounter;
      }
    }, 1000);
  }
}

The background activation notification displays at the top indicating active background mode. However, the timer does not appear to function correctly past the 5-minute mark.

Any suggestions on how to resolve this issue?

*** Update ****

Trying to trigger the function every 4 minutes in the background to ensure continuous operation but facing challenges:

function startTimerCounter() {
      this.timerCounter = 0;
      const objThis = this; //store this.

      if (this.timerCounter >= this.setTime) {
        this.backgroundMode.disable();
        this.goalTimerReached = true;
      } else {
        this.backgroundMode.enable();
        this.timerCounter = 0;
        const objThis = this; //store this.
        this.timer = setInterval(() => {
          if (objThis.timerCounter === objThis.setTime) {
            //onesignal notification
            clearInterval(objThis.timer);
          } else {
            ++objThis.timerCounter;
          }
        }, 1000);

     this.backgroundMode.on('activate').subscribe(() => {
        setInterval(function () {
          this.startTimerCounter();
        }, 240000);
      })
      }
    }

Answer №1

For optimal performance, make sure to implement the cordova-plugin-background plugin in your project.

document.addEventListener('deviceready', function () {

            cordova.plugins.backgroundMode.enable();

             cordova.plugins.backgroundMode.onactivate = function () {

               setInterval(function () {

                  YourFunctionHere();

                }, 300000);
             }
           }, false);

Your application will automatically refresh in the background every 5 minutes.

300000 milliseconds equals 5 minutes

Answer №2

For Android Users Only:

If you prefer not to use the cordova-plugin-background plugin and have the ability to modify your android app code, here is a solution. I will explain why the cordova-plugin-background may not work (this is just my assumption, so please read on if you are considering using this alternative).

Below is the android code snippet.

// First, you need to create an Android `jsbridge`
  webView.addJavascriptInterface(InJavaScriptLocalObj(), "android")
      @Suppress("unused")
  inner class InJavaScriptLocalObj {
/**
* @ script you want to run function in js code
  @ interval time unit is millisecond
*/
 @JavascriptInterface
 fun setInterval(script: String, interval: Long): Int {
            // TODO check need to cancel
            if (hashMap.size > 0) {
                hashMap.forEach { it.value.cancel() }
                hashMap.clear()
            }
            val jobSeek = scopeMain.launch {
                while (isActive) {
                    <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f5b47465c6f624e46416e4c5b4659465b56015d5a4160417a467b475d4a4e4b">[email protected]</a> {
                       //Run the script in here.
                        webView.evaluateJavascript(script),
                            object : ValueCallback<String?> {
                                override fun onReceiveValue(value: String?) {
                                    if (!value.isNullOrEmpty()){
                                
                                    }
                                }
                            })
                    }
                    delay(interval)
                }
            }
            val id = hashMap.size + 1

            hashMap[id] = jobSeek
            return id
        }

        @JavascriptInterface
        fun clearInterval(id: Int) {
            hashMap[id]?.cancel()
            hashMap.remove(id)
        }
  }

This is the JS code section.


android.setInterval(`interval()`)

function interval(){}

// If you are using Vue or another framework, make sure to execute this step

window.interval=interval()

// In my case with pineapple, I do this
window.interval=useCounterStore().interval()

However, there are some caveats to keep in mind:

In the background, the android webview cannot update views or make network requests. It can only trigger functions when native calls them.


Why does the cordova-plugin-background fail to work?

You must instruct the user to set the app to IgnoringBatteryOptimizations.

Here is a useful method:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Relay information between requests using a RESTful API and various data formats, such as JSON, XML, HTML

In a scenario with a REST API that can deliver JSON, XML, HTML, and other formats, the default response for browsers without JavaScript enabled is HTML. This API utilizes tokens for authentication and authorization. Within a traditional website project, t ...

The issue arises when attempting to execute an Ajax function within a JQuery append method, causing malfunction

My JQuery append function is calling an ajax function within the onChange method. Here is my code snippet: var data='<?php echo $data; ?>'; var tambah=1; var txt=1; function add_fullboard_dalam_kota(){ function showU(str) { ...

Error: Unable to access the 'ht_4year_risk_opt' property because it is null

When attempting to call the servlet that returns JSON data, I encounter an error while parsing the data. var jsonResponse = jQuery.parseJSON(data); var ht_4year_risk_opt = jsonResponse.ht_4year_risk_opt; ...

Acquire information from a JSON formatted string

I am having trouble extracting the first name from the JSON data provided below. While I am able to display the entire string using JavaScript [ alert(data); ], I am struggling to isolate just the first names. Any assistance would be greatly appreciated! ...

What is the most efficient way to combine a parameter string within a JavaScript function and append it to an HTML string?

Welcome to my HTML code snippet! <div id="content"></div> Afterwards, I add an input to #content: $( document ).ready(function() { // Handler for .ready() called. var parameter = "<p>Hello</p>"; $("#content").appe ...

Adding custom fields to the user model in MongoDB using Next Auth during login is not possible

When a user logs in via next auth, I am looking to include custom fields to the default user model. I followed the instructions provided in the official documentation at https://next-auth.js.org/tutorials/typeorm-custom-models. Here is the code snippet: ...

Updating a singular value in an array using jQuery/JavaScript

Within a Javascript function, I have created an array called HM_Array1. The contents of the array are listed below: HM_Array1 = [[,11,147,,,,,,,1,1,0,0,0,1,"csiSetBorder(this)","null",,,true,["&nbsp;&nbsp;&nbsp;Accoun&nbsp;&nbsp;& ...

The button's status changes to disabled until I click outside the input field in Angular

I am currently facing an issue with a form (heat index calculator) that requires 2 inputs - a dropdown and a button. The button is disabled when there are no inputs or if the inputs are invalid. Everything works correctly, except for the fact that even whe ...

Sharing a session with a Django template using jQuery

I am attempting to use $.load() to load a Django template that contains {% if user.is_authenticated %}. However, when the template is rendered on the server in response to an AJAX-generated HTTP request, the user object is undefined. Here is my_template.h ...

My code written using Visual Studio Code is not displaying properly when I view it in my browser

I have been following along with a tutorial series that can be found at this link. This link will take you to the third video in the series, but I have also followed and programmed alongside the first and second videos. After installing Visual Studio Code ...

Accessing an item within a JSON object using jQuery

Trying to access an element within a JSON object, part of the code is shown below: { " academy": { "business": { "E-commerce": [ I have successfully accessed the academy as the first element using the following code: $.getJSON("p ...

The issue of a false value not being correctly matched in Jasmine is causing problems

Currently, I am utilizing the following code to evaluate an element with aria-checked="false". expect((accessPolicyPage.listSelectAll).getAttribute("aria-checked")).toEqual("false"); The output is presenting as Expected [ 'false' ] to equal &ap ...

The drop-down button unexpectedly disappears when using Bootstrap in combination with jQuery autocomplete

I have some javascript code that is structured like: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Autocompl ...

Is there a way to create a Vue component that can process dynamic formulas similar to those used in

I am looking to create a component that has the ability to accept different formulas for computing the last column. The component should use these formulas in Vuex getters to store the total state values passed to it. Here are the specifications for the c ...

Establishing a user session with Node.js

I am new to the world of node.js and JavaScript in general. I have a piece of code that currently handles login functionality by checking if a user exists in a MYSQL database. This part is functioning correctly. Now, I wish to improve this feature by crea ...

Can terminating a POST XHR request be trusted?

Running an apache server with PHP 5.4. I've set up a form that sends an asynchronous request to the server and stops any previous requests if the button is clicked again before the current request is completed. If I repeatedly click the button quick ...

Unable to display "xyz" using console.log() function upon button click

Why isn't the JavaScript function being executed in this code snippet? <form> <select type="text" name="month" id="month"> <option value="01">January</option> <option value="02">February</option> ...

Only if there is an update in the SQL database, I wish to refresh the div

I have created a voting system and I am facing an issue with the data updating. I have implemented a setInterval function in javascript to load the data every 2 seconds, but it's not working as expected. There are no errors shown, but the data is not ...

What is the best way to isolate the elements from the specified dictionary that contain valid data?

I need to extract only the data for Flipkart from this array and create a new array containing just that information. json = [ { "amazon": [] }, { "flipkart": { "product_store": "Flipkart", ...

Error: React JS is unable to access the property 'path' because it is undefined

Currently, I am encountering an issue while setting the src of my image in React to this.props.file[0].path. The problem arises because this state has not been set yet, resulting in a TypeError: Cannot read property 'path' of undefined. To provid ...