Interval timer vs database field for over-the-air updates? - react-native

I want to provide OTA updates to users. My app uses real-time listeners on the database, so my question is whether to:
Set a 15 minute interval timer to check if an update is available (requires network call and long timers)
Database field for each user specifying when update is required (2X write calls per user)
Check when app is launched or foregrounded (latter may occur multiple times in a single session, would have to add a refractory period)
Some hybrid or other solution
... or perhaps I am worried too much about some best practice / optimized solution when the end user experience is not really affected by whichever option I choose?

My solution is basically an implementation of option 3. If a user is constantly switching in and out of the app, it will wait 15 minutes after the last update check to check again.
A useRef time variable that stores the last time the app was foregrounded
An update function that checks for updates
If available: fetch update and reload app
A useEffect to check for updates on launch
A useEffect to listen to changes in AppState
If app was foregrounded && time.current + 15000 < Date.now(): check for updates

Related

YouTrack Lite How to automatically track time

Is there anyway to track time with just Start/End Button with automatic adding to Spent time field?
Tried Clockify. It doesn't work at Lite version and even in Classical one it just track specific task inside Clockify app without transferring to YouTrack Spent Time Field.
Workflow called workTimer that starts a timer each time issue is moved to 'In progress' state is not an option as we don't use field State.
It is possible to use YouTrack's default Stopwatch-style work timer (https://www.jetbrains.com/help/youtrack/incloud/Workflow-Standalone-Work-Timer.html). It doesn't use the State field. Instead, it starts the timer when the corresponding Timer field is set to Start. After setting the Timer field to Stop, the timer stops and adjusts the Spent time field accordingly. You can attach the default workflow to your project; after that, the workflow will suggest you to add all required fields automatically.
Please note that work items are not displayed in YouTrack Lite at the moment. However, the nearest major YouTrack release will solve this, bringing time tracking for YouTrack Lite. So for now you can see only the total spent time value of each issue. To see the work items themselves, you'll need to switch to YouTrack Classic.

React Native/Firebase App - want countdown functionality to cease if user exits app

I have built a react native app/game where a user has 30 mins to finish a task....when they start task, the 30 mins starts to countdown and it is registered in DB (Firebase) that user is "in play". When they complete task (or 30 mins run out) then DB is again updated to "not in play".
Countdown function is operating on phone and not on server.
Problem is that if the user exits the app, then the counter on the phone ceases (the user is no longer "in play") but the DB does not know about it.....there appears to be no "user has exited app" event/handler that I can use to let DB know that user has quit.
I was thinking maybe the countdown logic should be running on backend but I cant think how.....any ideas?
Currently there is no way to handle app terminated in React Native so I think your best shot is to implement it on the backend.
How about when the user starts, you save the time the user started, and if the time difference between now and when the countdown was started surpasses 30 minutes the user is no longer "in play".
One way to detect that the user has left the game would be with Firebase's onDisconnect handler. With this call you register a write operation on the database that is executed when the server detects that the client is gone.
The server can detect this in two ways:
If the client disconnects cleanly, it sends a message to the server that it is disconnecting and the server runs the disconnect handlers for that client straight away.
If the client disconnects in another way, the server will detect that the client is gone when the socket times out, which may take a few minutes.
So in your case you could use an onDisconnect handler to either remove the player from the game, or otherwise mark them as "gone".
The only problem with this approach is that dirty disconnects may take a few minutes, which might be too long for your scenario.
An alternative would be to have the client write a message into the database periodically to signify that it's still here, e.g. a lastUpdated timestamp.
You can then in any code that reads the data use that timestamp to detect if the player was still recently playing, and consider them "gone" after a certain period that works well for your game. This code can then remove the player from the database.
This code can run in a server-side component if you want, but I've in the past also run this type of code in the client and then used (server-side) security rules to ensure it can only remove users that are "gone".

Execute a transition a specific date with NServiceBus

I'm working on a system where the lifetime of a subscription is handle with a state machine and I'm looking at NServiceBus as a replacement for the management of transitions between states.
Example
A customer has an active internet subscription and would like to cancel it 3 months in the future.
Current Solution
A transition is created in the database e.g.
tranistionId: 10000,
subscriptionId: 1337,
transition: "execute-inactivation"
due-date: {current date + 3 months}
The table is scanned every 10s to see if there are any new/due transitions.
NServiceBus
I think it would be possible to replicate the current solution with:
Schedule.Every(TimeSpan.FromSeconds(5)).Action(() =>
{
Bus.Send<CheckForDueTransitions>();
});
But that will not remove the problem with the chattiness against the database.
Another important feature is that's possible to a abort a queued transition e.g. cancel the cancellation.
Is there a preferred NServiceBus solution for my problem?
I would suggest looking at NServiceBus Sagas. You might think of each subscription being its own long running process (Saga instance), and using the Timeout Manager to manage them. You could then use the timeout functionality to cancel your subscriptions automatically, on-demand, or if a users extends their subscription, create a new timeout for that subscription to the new expiry date.

Schedule daily update of IconBadgeNumber from applicationDidEnterBackground

I've been able to set an application badge number to my iPhone app and updating it once the user interacts with my app:
[[UIApplication sharedApplication ] setApplicationIconBadgeNumber:currNrOfNotif];
What I wont though, is for this process to occur while in background mode, ie from within applicationDidEnterBackground or similar. I would like this process to be scheduled to run daily, every night at 00:00 00:00 and take the current number in setApplicationIconBadgeNumber and decrement it by -1. No need for push notifications (or any server kind) in other words as the only thing that will happen is a change of the badge number value.
First of all, how do I schedule an activity to occur while app's in background mode, without using remote server push notifications?
Secondly, how do I get or fetch the current application notification badge value and decrement it by one?
In this post, some people argue it simply can't be done even with local notifications and that server side push's required. One person, however, states it can be done by scheduling it by midnight. Who's right, and can someone please propose a solution to this?

iCloud KeyValue store not recognized on first launch

My app uses iCloud (key-value store) to sync an unique id between multiple devices. This works accept at the point were it really has to work, at the first launch of the app. It looks like the device isn't yet familiar with the values from iCloud at first launch, only after the app is installed and has been running for a while.
I check for the iCloud value in the viewDidLoad function on main view of the app.
So, my questions:
Is this the expected behavior?
If yes, is there another solution?
Could it be the case this is only a problem when running from Xcode, not the shipping version? If so, how to test?
Thanks!
Jasper
I had a similar issue where the NSUbiquitousKeyValueStoreDidChangeExternallyNotification wasn't triggering on the first launch after install, no matter how long I waited. Setting an initial key in the NSUBiquitousKeyValueStore seemed to solve this.
Immediately after adding the observer to the default store, I call:
[[NSUbiquitousKeyValueStore defaultStore] setString:#"testValue" forKey:#"testKey"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
I use different keys (i.e. not testKey) for the actual data I want to sync.
When you first run an iCloud enabled App it has to pull all the data from Apple servers. The time it takes to do so depends on many things like what kind of network you're currently on (Edge, 3G, GPRS, WLAN). It also depends on how much traffic the iCloud server currently has to handle so the request to the iCloud server may take a few more seconds, no matter what type of network connectivity you have.
To sum it up: Yes, it sounds absolutely normal.
If running your App depends on those settings consider implementing a "Wait" or "Loading" view that stays on the screen as long as it takes for the App to perform a initial synch and load all needed data from the cloud. To not block the UI forever also implement a timeout for this view (if iCloud data not loaded within X seconds, dismiss the view and notify user).
You have no guarantee NSUbiquitousKeyValueStore would have finished its first synchronization as your app is launched for the first time. (In fact, on iOS 5, it's often starting to sync as you launch your app for the first time).
There is no way to know if the first initial sync has already happened, is ongoing or has finished. You can (in fact should) subscribe to NSUbiquitousKeyValueStoreDidChangeExternallyNotification. The trick is that if your store is empty on the iCloud server, you won't get any notification after the initial sync (since your local store is empty and the cloud store is empty as well, nothing really changed "externally" after the initial sync…)
Normally, you should not rely on the initial sync being done.
Be optimist at launch, even if your store is empty, push your values (e.g. your unique id) right away. If the initial sync happens concurrently or after and there is already some value on the server, your local values will be reset to the server values and you will get the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification with the NSUbiquitousKeyValueStoreInitialSyncChange reason.
Finally, if you really think knowing about the initial sync being completed or not, please file a bug to bugreport.apple.com and explain why you really need that.