Delay Google Cloud Function - swift

I have a swift iPhone application paired with Google Firebase. Within the application the user will complete an action (press a button). At this point, I would like to schedule a Google Firebase Function to run 45 minutes after the user action. However, I would like this function to be able to be cancelled when another action (press a button) is completed within the iPhone application. I could do this within swift with a timer but that wouldn't work if the user closes the application.
I am not opposed to using a third party scheduler or something of the sorts. Any suggestion welcome.
I have looked at the possible duplicate questions and answers (Cloud Functions for Firebase trigger on time?) However, most of the links in that answer are deprecated and out of date. Also, that is referring to scheduling something repeatedly. For example, every hour, once a day, etc... I am looking to schedule the job 45 minutes after trigger (user action) with the ability to cancel the job within that 45 minute window.

Would a delayed Cloud Task work for you?
You can create a Cloud Task that is delayed and calls your function through an HTTP trigger. The task can be then cancelled if your user performs the second action you desribe. There is a number of dedicated client libraries for Cloud Tasks, as well as a REST API.

There is no built-in way to delay the trigger on a Cloud Function, or to re-trigger it after a certain delay. The best way I can think of using Cloud Functions is to set up a periodic trigger as shown here: Cloud Functions for Firebase trigger on time?. And then in that periodic trigger you determine what jobs have to run.

You could use https://delayedrequest.com as long as you can invoke your Firebase Function via an http request.

I recently had a similar issue that was solved by using Cloud Scheduler and Firestore. I set up a job that would trigger a cloud function every 5 minutes that would check a Firestore collection. It would retrieve the data on when a cloud function should be triggered and trigger it. It also depends how accurate you want your time triggers to be. It's not optimal to have it trigger all the time for no reason but in my case it worked.

Javascript/Typescript allows you to delay using the setTimeout function
// time is in milliseconds
function delay(time:number) {
return new Promise(res => {
setTimeout(() => {
res("VALUE TO RESOLVE");
}, time);
});
}
Then call this by doing const res = await delay(1000);

Related

MIKROS Analytics not showing (Unity project)

I do not see any tracked events on MIKROS Analytics. I have followed all the steps from the Get Started guide.
My app is approved and I already have an "appGameId" and my "apiKey". I am using the Production "apiKey" for now.
Some other information. I have auto initialization enabled under Mikros Settings in the Inspector. I also tested without auto initialization and initialized the MIKROS SDK at app start like this,
MikrosManager.Instance.InitializeMikrosSDK();
I tried to log a custom event like this,
// log events
AnalyticsController.LogEvent("mikros_analytics_test", "parameter", "app_open", (Hashtable customEventWholeData) =>
{
// handle success
},
onFailure =>
{
// handle failure
});
Any idea why I am unable to see any events on the dashboard? Or what step(s) I am missing?
Don't forget to define the namespaces at the top of your scripts as well.
using MikrosApiClient;
using MikrosApiClient.MikrosAnalytics;
It takes some time after the app is not being used before all events are fully logged. However, you can manually log them by calling:
AnalyticsController.FlushEvents();
Also make sure you have the following at the top of your script:
using MikrosApiClient;
using MikrosApiClient.MikrosAnalytics;
Ref: https://developer.tatumgames.com/documentation/log-events
Similar to other analytic services such as Firebase Analytics or Unity Analytics, MIKROS Analytics queues your events and will send them out in batches. There are certain criteria required in order for the batched events to be sent off.
While both Firebase and Unity can take up to a maximum of 24 hours before events can be viewed on their dashboards, MIKROS has a max time of about 10 hours. However, in most cases MIKROS tracked events will be posted more immediately. The 10 hour timeframe is when the entire batch of events is forced cleared from the queue.
If you want more control of how immediate events are sent off you could force event uploads using flush(). Call the method after you have tracked your events.
MikrosManager.Instance.AnalyticsController.FlushEvents();
It is not really necessary, but it's an option available to you.

Is there a standard / built-in way to handle race conditions with CKFetchRecordZoneChangesOperation?

I'm building my first CloudKit application, and am using CKFetchRecordZoneChangesOperation on startup to get any new records changed while the current device was offline.
I am also calling CKFetchRecordZoneChangesOperation when I receive a subscription notification of changes.
It is possible the subscription notification could come in before the startup call finishes. I am currently using a lock to prevent the 2nd call from starting until the recordZoneFetchCompletionBlock handler is called, signalling that the first one is done. This works, but it also smells a bit hacky.

Flutter/firebase: execute function at specific time

How can I execute a function at a specific time with flutter and firebase? I want to allow the user of my app to send messages to other users at a specific time. Right now, they are sent when the message is created, but I would like to allow the user to schedule the message.
Any idea? I have looked at the Timer class of Flutter, but it does not seem to be useful for this.
According to me handling this on flutter(frontend) will be a bad idea. You can look into firebase cloud function and scheduling of cloud functions to achieve the result. For example, you can have a boolean to show/hide the message in your message model and use cloud function to update it accordingly on the scheduled time.

Is using Firestore Cloud functions different from using active listeners within the application?

I've been trying to get an answer to my issue for weeks now without any luck.
I have an app in swift that displays a few labels on the screen. I want the label text to change everyday at midnight, and I want to be able to decide what the label should say from my machine.
I've been told to use either active listeners or cloud functions.
The video below shows a dev using firebase cloud functions to alter text in real time on an app.
https://www.youtube.com/watch?v=Z87OZtIYC_0
How is this any different from active listeners which also do the same?
Objectively speaking, what suits my use case more?
To execute a function at midnight to make a UI change first requires that the app is open. If the app isn't even open then there isn't a UI to update. Therefore, there is no sense in tasking the server with this function because the app may not even be open. And the task of updating the UI should be the responsibility of the client, anyway.
Therefore, create a timer on the client (in your app) that makes a call every midnight to get data from the server that populates the labels. What you need is to create a Timer object that fires in n seconds to midnight that has an interval of 1 day that repeats infinitely. It may look something like this:
var midnightTimer: Timer?
midnightTimer = Timer(fire: Date().addingTimeInterval(secondsToMidnight), interval: oneDayInSeconds, repeats: true) { (timer) in
self.updateLabels()
}
RunLoop.main.add(midnightTimer!, forMode: .common)

Recurring function at date/time

I'm trying to call a function when my macOS application is in any state, including terminated. Here is what i'm trying to accomplish:
Schedule a function (much like DispatchQueue.main.asyncAfter()) to run daily at a given time (let's say 9AM). I would like to add a feature to my application that allows a user to pick a time of day, and have an Alamofire POST request run at that time every day.
I have tried using a Runloop, and more recently Grand Central Dispatch:
DispatchQueue.main.asyncAfter(wallDeadline: DispatchWallTime.now() + .seconds(60)) {
//Alamofire
}
I can easily accomplish this while the application is running with a timer, but have yet to find a way to accomplish this in the background, with the app running.
This may be pretty heavy to implement (i.e. not straightforward), but if you want a task to run even if your app is terminated, you might need to consider writing your own LaunchAgent.
The trick here would be for the agent to be able to interact with your application (retrieving or sending shared information).