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

Utilize the Webstorm debugger in conjunction with node.js for seamless debugging

Several weeks ago, I attempted to get the webstorm debugger up and running, but unfortunately, it didn't work. Now, I'm giving it another shot, but I'm faced with the same outcome. I am following the instructions outlined here: http://www.j ...

Certain cases will see success with iPhone jquery/ajax functionality, while others may encounter

I am facing an issue with multiple pages in my project that utilize AJAX to submit a form to django. While the buttons work perfectly on various platforms and browsers like Chrome, Firefox, and desktop Safari, they seem to malfunction specifically on mobil ...

When incorporating sequelize's belongsTo and hasOne methods, you may encounter an issue where the call stack size surpass

Within my Discussion entity, I have: Discussion.hasOne(sequelize.import('./sound'), { relations: false }) While in the Sound entity, the relationship is defined as: Sound.belongsTo(sequelize.import('./discussion')) To load t ...

Ways to verify if one div in jQuery contains identical text to another div

I need help with a jQuery script to remove duplicate text in div elements Here's the requirement: If div1 contains the text "hi" and div2 also contains "hi", then div2 should be removed Below is my current code snippet: <script src="https:/ ...

Discovering the specific DOM element that has been clicked using only JavaScript

Looking to enhance my HTML document with interactivity, I wanted to achieve a feature where clicking on a div element would display its respective id. I attempted the following approach: window.onload = function() { associateIds(); clicked(); } fu ...

Using cfajaxproxy in conjunction with URL rewriting capabilities

I have successfully integrated the cfajaxproxy tag, but encountered an issue with the cfc's location in the root directory of my site. When accessing a page within the root directory through a rewritten URL (e.g. mysite.com/one/two/ -> mysite.com/two ...

"Using JavaScript to trigger a button click event, and then

I have a question that I think may sound silly, but here it is. I have this code snippet: <script type="text/javascript"> $(document).ready(function(){ var email_value = prompt('Please enter your email address'); if(email_value !== null){ ...

What limitations prevent me from using "await .getAttribute()" in Protractor, despite the fact that it does return a promise?

I have been working on transitioning my Protractor tests from using the selenium control flow to async/await. However, I am facing an issue where it is not allowing me to use await for the .getAttribute() function. Each time I try, I receive the error mess ...

Tips for halting a MySQL database transaction within a NodeJS environment using expressJS

Recently, I encountered a coding challenge that involved managing a long database transaction initiated by a user. The scenario was such that the user inadvertently updated 20 million entries instead of the intended 2 million, causing a significant impact ...

Validate the checkbox with Vuelidate only when the specified property is set to true

I have a website login form where users may need to check a specific checkbox before logging in. Here is part of the Vue component code that handles this functionality: <script setup lang="ts"> import {ref, defineProps} from 'vue&a ...

Having Trouble with Shopify's Asynchronous Ajax Add to Cart Feature?

I have developed a unique Shopify page design that allows users to add multiple items to their cart using Shopify's Ajax API. I've created a test version of the page for demonstration: Below is the current javascript code I am using to enable as ...

What is the best way to determine the left and top coordinates when resizing a draggable image within a container?

I am struggling to correctly scale the image and set the left (x) and top (y) positions. Here is the code from my template: <div id="container" :style="`height: ${height}px;width: ${size}px;overflow: hidden;position: relative;`"> ...

Client-side rendering for NextJS server components is also supported

I am currently working with Material UI v5.11.16 in a nextjs environment using v13.3.0. I followed the official documentation setup for my nextjs project which can be found here. So far, I have successfully integrated Material UI components without having ...

What is the correct way to add an object to a specific array in express.js?

My goal in the following function is to write a JSON file with an array of data as strings. However, the push() function, which is commented out, is causing the code to not execute as intended. Everything works fine without that line of code, but I do need ...

Vue.js custom confirmation component failing to open within v-menu

I am having trouble displaying a confirmation component every time a button in the header is clicked. Currently, it only opens when clicking elements outside of the dropdown using v-menu. App.vue <template> {{isConfirmDialogVisible}} <div cla ...

A Guide to Effortlessly Implementing moment.js into a React TypeScript Application

I'm attempting to implement code splitting and one of the specific packages I want to separate into its own chunk is moment.js. Here's how I'm doing it: const myFunc = async (currentNumber) => { const moment = (await import('momen ...

Is OnPush Change Detection failing to detect state changes?

Curious about the issue with the OnPush change detection strategy not functioning properly in this demonstration. My understanding is that OnPush change detection should activate when a property reference changes. To ensure this, a new array must be set e ...

Vue.js variable routes present an issue where the Favicon fails to appear

I've successfully set my favicon in the index.html file for my Vue webpack SPA. It displays properly when I visit the main site or any standard route, but it fails to show up when I navigate to a dynamic route (path: "/traduzione/:translation"). I&ap ...

An odd issue has arisen where the website functions properly in Firefox 3.0 but encounters problems when accessed in Firefox 3

Could someone investigate this issue for me? When you click on the showcase and then on the logo, a modal window should open with the logo. It works perfectly in FF 3.0, but in FF 3.5, the tab switches from showcase to home after clicking the logo. Even ...

Sending form information through AjaxPassing information from a form using

Currently, I am working on a project where one page opens a thickbox of another page that contains a form. Once the form is submitted and data is written to the database, I need the parent page of the thickbox to update specific rows of the form that have ...