Can't retrive data in Timer

Hi, noob here trying to build my first MAUI app with Backendless. I’m trying to set a timer to do some daily data processing with data in one of my tables. But I can’t get it to retrieve any data, and I don’t get any errors. Could someone tell me (in very beginner friendly words) why it isn’t working? Thanks.

/**
* DailyResourceUpdate timer.
* It is executed according to the schedule
*/
Backendless.ServerCode.addTimer({

  name: 'DailyResourceUpdate',

  startDate: 1725571800000,  // Startdatum för timer
  
  frequency: {
    schedule: 'daily',       // Körs dagligen
    repeat: {'every': 1}     // Upprepa varje dag
  },

  /**
  * @param {Object} req
  * @param {String} req.context Application Version Id
  */
  execute(req) {
    console.log("Timer running... Trying to fetch posts from the table Realms");
    
    // Fetch all posts from Realms
    Backendless.Data.of("Realms").find({ pageSize: 100 }).then(function(records) {
      console.log(`Number of posts retrieved: ${records.length}`);
      if (records.length === 0) {
        console.log("No posts found.");
        return; // Abort, no posts found
      }
      
      // Do calculations for each post
      records.forEach(function(record) {
        console.log(`Updating post with id: ${record.objectId}`);
        
        // Calculations on specific fields
        record.goldValue = record.goldValue + record.popValue;  
        record.foodRate = 0.9 + 0.3 * (1 - (record.popValue / 8));  
        record.popValue = record.popValue * record.foodRate;   
        
        console.log(`Post calculations: goldValue = ${record.goldValue}, popValue = ${record.popValue}`);
        
        // Save updated posts to database
        Backendless.Data.of("Realms").save(record)
          .then(function(updatedRecord) {
            console.log("Post updated: ", updatedRecord);
          })
          .catch(function(error) {
            console.error("Error updating post: ", error.message);
          });
      });
    }).catch(function(error) {
      console.error("Error retrieving posts: ", error.message);
    });
  }
});

This is what I get from the log:
18:38:11.69 | SERVER_CODE | INFO | [544439] Building ServerCode Model for path (/opt/backendless/repo/2d65b412-f4c2-4703-9d74-55dd4785495a/files/servercode/JS/default/PRODUCTION)

18:38:11.70 | SERVER_CODE | INFO | [544439] ServerCode Model built in 5ms

18:38:11.73 | SERVER_CODE | INFO | [544439] [8A5DD4FA-6FE4-46DE-AD96-3D28202EAE84] [INVOKE TIMER] DailyResourceUpdate

18:38:11.77 | SERVER_CODE | INFO | [544439] Timer running… Trying to fetch posts from the table Realms

18:38:11.142 | SERVER_CODE | INFO | [544439] Processing finished in 84.970ms

Possibly due to a bug in your code.

Suggestion:

before putting the code in a timer, run it as an API service or just standalone node app. This will give you more insight into what went wrong.

Ok, that was a great tip. I did find a problem with my Timer code when I made an API Service of it, and got the problem fixed. However when I’m trying to take that working code back to my Timer I still have the same problem, it doesn’t fetch anything from the database to process. Any tips?

Working code from my API Service

// Klass för logik och beräkningar
class DataFetchService {
  constructor() {}

  // Metod för att hämta och uppdatera data
  fetchData() {
    console.log("API-service körs: Försöker hämta poster från Realms-tabellen...");

    // Hämta alla poster från Realms-tabellen
    return Backendless.Data.of("Realms").find({ pageSize: 100 }).then(function(records) {
      console.log(`Antal poster som hämtades: ${records.length}`);
      if (records.length === 0) {
        console.log("Inga poster hittades.");
        return "Inga poster hittades.";
      }

      // Gå igenom varje post och gör beräkningar
      records.forEach(function(record) {
        console.log(`Uppdaterar post med ID: ${record.objectId}`);

        // Gör dina beräkningar här på flera fält i varje post
        record.goldValue = record.goldValue + record.popValue;
        record.foodRate = 0.9 + 0.3 * (1 - (record.popValue / 8));
        record.popValue = record.popValue * record.foodRate;

        console.log(`Efter beräkningar: goldValue = ${record.goldValue}, popValue = ${record.popValue}`);

        // Spara tillbaka uppdaterade poster till databasen
        Backendless.Data.of("Realms").save(record)
          .then(function(updatedRecord) {
            console.log("Post uppdaterad: ", updatedRecord);
          })
          .catch(function(error) {
            console.error("Fel vid uppdatering av post: ", error.message);
          });
      });

      return "Uppdateringar slutförda!";
    }).catch(function(error) {
      console.error("Fel vid hämtning av poster: ", error.message);
      return "Fel vid hämtning av poster: " + error.message;
    });
  }
}

// Registrera API-tjänsten i Backendless
Backendless.ServerCode.addService(DataFetchService);

Non-working code from my timer

/**
* DailyResourceUpdate timer.
* It is executed according to the schedule
*/
Backendless.ServerCode.addTimer({
  name: 'DailyResourceUpdate',
  startDate: 1725659281000,  // Justera startdatum om nödvändigt
  frequency: {
    schedule: 'daily',       // Körs dagligen
    repeat: { every: 1 }     // Upprepa varje dag
  },

  /**
  * @param {Object} req
  * @param {String} req.context Application Version Id
  */
  execute(req) {
    console.log("Timer körs: Försöker hämta poster från Realms-tabellen...");

    // Hämta alla poster från Realms-tabellen
    Backendless.Data.of("Realms").find({ pageSize: 100 }).then(function(records) {
      console.log(`Antal poster som hämtades: ${records.length}`);
      if (records.length === 0) {
        console.log("Inga poster hittades.");
        return;
      }

      // Gå igenom varje post och gör beräkningar
      records.forEach(function(record) {
        console.log(`Uppdaterar post med ID: ${record.objectId}`);

        // Gör dina beräkningar här på flera fält i varje post
        record.goldValue = record.goldValue + record.popValue;
        record.foodRate = 0.9 + 0.3 * (1 - (record.popValue / 8));
        record.popValue = record.popValue * record.foodRate;

        console.log(`Efter beräkningar: goldValue = ${record.goldValue}, popValue = ${record.popValue}`);

        // Spara tillbaka uppdaterade poster till databasen
        Backendless.Data.of("Realms").save(record)
          .then(function(updatedRecord) {
            console.log("Post uppdaterad: ", updatedRecord);
          })
          .catch(function(error) {
            console.error("Fel vid uppdatering av post: ", error.message);
          });
      });

    }).catch(function(error) {
      console.error("Fel vid hämtning av poster: ", error.message);
    });
  }
});

Hello @Dennis_Liljedahl

I recommend that you add logging for each operation, so that you can then see at what step the problem occurs. You can see the logs in real-time logging.
https://backendless.com/docs/js/ut_logging_a_message.html

When you start the timer manually, the logic is also not executed?

Regards,
Inna

Hi,

I have implemented serveral logging steps, you can see them in my code (although they are in Swedish in my latest code…). But they never get to the part where data actually have been fetched and I can’t get any error codes.

Yes it’s still the same problem when I run the timer manually.

I consulted with my colleagues about your code. We can see that you are creating a service inside the timer. You can’t do that. You need to create a separate API service, and using the timer you can call methods of this service.

Regards,
Inna

Alright, that kinda explains it :wink:

Thanks!