minimumFetchInterval in Firebase remote config - android

I'm using remote config to prompt user for a new update. What should I use for the minimumFetchInterval?
The dilemma is that, if I keep this number too low (let's say 5 or 10 seconds), then it would increase the calls to Firebase; and, if I keep it as something like 60 minutes, then the update would be delivered late to the user.
Some advice or suggestions would be helpful.

From the Firebase documentation on throttling in Remote Config:
The default and recommended production fetch interval for Remote Config is 12 hours
So you should set it to 12 hours in production.
From the same page:
During app development, you might want to refresh the cache very frequently (many times per hour) to let you rapidly iterate as you develop and test your app. To accommodate rapid iteration on a project with numerous developers, you can temporarily add a property with a low minimum fetch interval (Settings.minimumFetchIntervalMillis) in your app.
So you can set it much shorter during development, because:
Keep in mind that this setting should be used for development only, not for an app running in production. If you're just testing your app with a small 10-person development team, you are unlikely to hit the hourly service-side quota limits. But if you pushed your app out to thousands of test users with a very low minimum fetch interval, your app would probably hit this quota.

Related

Syncing with server in specific interval at non-active hours

I want to sync the data with server between 12 am - 6 am only.
I have solutions like WorkManager and sync adapter at my disposal.
But some manufactures put restrictions on these work managers and syncadapter also.
What is a sure shot solution that a network request will can be made between these non active hours(most users are not using the app) ?
There is no sure solution. This is Android. Every vendor can do whatever they like.
What restrictions you are talking about? Because you are saying "some vendors"? In general Android applies restrictions related to how much time you can be executed per 24 hours period and how much network you can use. It is dependant on the Power Bucket you are in. And the Power Bucket itself depends on how often the user interacts with your app. Check here:
https://developer.android.com/topic/performance/power/power-details
You can implement a dialog asking the user to exempt you from Battery Optimization. This will fix the restrictions on most vendors. Check here:
https://developer.android.com/training/monitoring-device-state/doze-standby#support_for_other_use_cases

Remote Config throttling : The counter is per device or sum all calls?

The documentation says:
If an app fetches too many times in a short time period, fetch calls
are throttled and the SDK returns
FirebaseRemoteConfigFetchThrottledException. Before SDK version
17.0.0, the limit was 5 fetch requests in a 60 minute window (newer versions have more permissive limits).
This policy consider the fetch from all devices and running Apps on my project or the counter is by device?
For example, 5 different devices call fetch using my App. If a sixth device call again, in less than 1 hour, will be throttled ? Or each device can fetch 5 times before be throttled ?
Background:
I have implemented the "real time propagation" for remote config, as described on the documentation here and here
Is working correctly.
When i publish a new configuration, my app receive a silent notification. I set one flag to indicate that a new update is available and then. When user opens the App again, i verify the flag, set the fetchInterval to 0 and force fetch configuration from the firebase server. But im worried that this strategy might be throttled
Maybe this answer comes a bit late but in case someone else is useful the throttled state is by device, I was able to check this for myself, debugging with other devices at the same time that one of my devices was in the throttled state. You can also check for yourself by removing the application and installing it again. Firebase will take your device as a new one and it will no longer be in a throttled state.

Proper way to tackle and resolve "Excessive network usage (background)"

Problem Background
Currently, we have facing "Excessive network usage (background)" from Android Vital report. Last 30 days is 0.04%, but we're only Better than 9%
Last 30 days - 0.04%
Benchmark - Better than 9%
Since only better than 9% looks like a scary thing. We decide to look into this issue seriously.
The app is a note taking app (https://play.google.com/store/apps/details?id=com.yocto.wenote), which provides an optional feature - sync to cloud in background after the app close.
This is how we perform sync to cloud in background.
We use WorkManager.
In Application onPause, Schedule OneTimeWorkRequest, with constraint NetworkType.CONNECTED. The worker is scheduled to start with delay 8 seconds.
In case failure, we retry using BackoffPolicy.LINEAR, with delay time 1.5 hours.
The maximum number of retry is 1 time. That's mean, after the app close till the app re-open again. The maximum number of execution, of sync to cloud process is 2.
The size of data is vary, can be few KB till few hundred MB.
Additional information how we perform sync
We are using Google Drive REST API.
We are performing downloading of a zip file from Google Drive App Data folder, perform data merging in local, then zip, and re-upload the single zip file back to Google Drive App Data folder.
The zip file size can ranged from few KB, to few hundred MB. This is because our note taking app supports image as attachment.
Analysis
The only information we have is https://developer.android.com/topic/performance/vitals/bg-network-usage .
When an app connects to the mobile network in the background, the app
wakes up the CPU and turns on the radio. Doing so repeatedly can run
down a device's battery. An app is considered to be running in the
background if it is in the PROCESS_STATE_BACKGROUND or
PROCESS_STATE_CACHED state.
...
...
... Android vitals considers background network usage excessive when an
app is sending and receiving a combined total of 50 MB per hour while
running in the background in 0.10% of battery sessions.
We start the background sync job, 8 seconds after Application's onPause. During that period, will the app inside or outside PROCESS_STATE_BACKGROUND/PROCESS_STATE_CACHED? How can we avoid running inside PROCESS_STATE_BACKGROUND/PROCESS_STATE_CACHED?
What does it mean by "running in the background in 0.10% of battery sessions."? How can we avoid such?
Another assumption, is sync file is too large, and using too much data. Soon, we notice this assumption might not be true. We notice according to "Hourly mobile network usage (background)", the data size is from 0MB to 5MB.
Questions
My questions are
What is the actual root cause for such "Excessive network usage (background)" warning? How can we accurately find out the root cause.
How does other apps (Like Google Photo, Google Keep, Google Doc, ...) which perform background sync, tackle this problem?
For your first question, "Excessive network usage (background)" is triggered when:
... an app is sending and receiving a combined total of 50 MB per hour while running in the background in 0.10% of battery sessions. A battery session refers to the interval between two full battery charges.
Source
To identify what is causing this, try using Battery Historian to analyse your app's battery usage over time. For us, it helped identify a repeating wakelock we didn't intend to introduce.
Here's an example of the output, showing us that excessive BLE scanning is causing a major battery impact:
For your second question, WorkManager is likely what you are after, as you correctly identified. This allows you to schedule a task, as well as a window you'd like it to occur in. Using this allows the OS to optimise task scheduling for you, along with other app's jobs. For example, instead of 6 apps all waking the device up every 10 minutes for their hourly task, it can be scheduled to happen for all 6 apps at the same time, increasing the time spent in doze mode.
Notice the screenshot above includes a "JobScheduler Jobs" tab. After running an analysis you'll be able to see how your jobs are actually performing:
I've previously used Firebase JobDispatcher with great success (tutorial I wrote), which extends the OS' JobScheduler API and is ultimately similar.
I see you're using WorkManager now (Jetpack's version of JobDispatcher), but with 8 seconds there's no chance for the OS to optimise your jobs. Is there any capacity of scheduling them with a minimum of a few seconds, and as large a maximum as possible?
Further improvements
However, your current task scheduling setup may not be the root cause. Here's a few additional ideas that may provide the battery improvement you need. The usefulness of them will become clearer after you've run Battery Historian and identified the root cause:
Consider whether wifi-only is a feasible default / option for data syncing. You'll experience better battery usage, fewer network issues, and likely better customer satisfaction.
Why does a note taking app need to sync a few hundred MB? Can you perhaps just sync the note that has changed, instead of the entire list of notes every time?

Firebase JobDispatcher vs Evernote Android Job - how do these two compare?

Currently, in Android, to do a task periodically based on time or any other factors like charging state, network state etc, the basic three options are: Android AlarmManager (which works periodically based on time), GCMTaskService (requires Google Play Service on device) and JobScheduler (requires Android Version > 21). Recently, I've come across these two libraries for scheduling jobs, one from Firebase and one from Evernote.
My primary question is: How do these two libraries compare? What are their strength and weaknesses?
I want to build an app where a user is reminded of taking medicines periodically after certain time period.
My secondary question is: would simple AlarmManager suffice for this purpose, or should I go for any of these two libraries?
Thanks.
How do these two libraries compare? What are their strength and weaknesses?
There's a nice table of comparison in Firebase JobDispatcher github page:
The key difference is Google Play services presence: Firebase needs device to have it installed, whereas Evernote is Play Services independent.
I want to build an app where a user is reminded of taking medicines periodically after certain time period. Would simple AlarmManager suffice for this purpose, or should I go for any of these two libraries?
The rule of thumb is, that most possibly you won't need AlarmManager, because it is a battery drainer. One of key features of job dispatchers is that they combine jobs and execute them in a single window, thus device won't wake up too often.
You'd better stick with job dispatchers, unless taking medicines should have exact timing like alarm (e.g. you want to notify user to take the medicine exactly in 3 hours).

Google Analytics iOS SDK "1 second sessions" (possibly background sessions?)

Google Analytics (using iOS SDK version 3.14 and it's built in sessions tracking) is reporting a significant percentage of app sessions as 1 second.
Maybe users are launching an app to view a page and (effectively) then instantly leaving the app, but that seems unlikely (that it should continue as the top use case. You think such users would stop using or uninstall.)
Initially I suspected this was related to "background fetch" but when I look at a prior incarnation of the application (that did not have background fetch enabled or used) I still see these (seemingly) bogus sessions also. That application (pre iOS9) had no universal links.
The (obvious) reason I don't want to see these sessions (especially if from automated action not user action) is it removes all value of "user behavior"; i.e. loyalty, recency and skews "average session length". These are the main reasons I want to use GA, i.e. to see if folks are using it more/valuing it more.
My questions:
What might these sessions be caused by? Are they bogus?
If bogus, how can I stop them?
Can I ensure new "background fetch" code doesn't somehow trigger them?
Some things I've considered / looked into:
I am seeing a similarly large set of "short sessions" on an Android application (this application's peer) and again with extremely high numbers. I've been wondering if this was a result of a web searches & site links, with those site links automatically loading the app, and the a (very) quick user "move on". (Universal linking is something the new iOS application is working towards, but doesn't see much of yet.) Given it is not that on iOS I am starting to doubt that it is that on Android.
There is a "optOut" option on GA. That feels like a sledgehammer solution to this walnut problem. It is also a persistent setting, which feels risky to use for a transient situation. I could attempt to toggle it at applicationDidEnterBackground / applicationDidBecomeActive (and will if it is deemed the solution) but worry it could have negative side-effects.
One can have multiple trackers. I am planning to attempt one for human foreground activity and one for background operations (which might allow time /event tracking when in background, w/o impacting human user tracking numbers. That said, I don't know / believe this is the cause of the bogus sessions. )
One can manage sessions manually and also customize the sessions interval timeout, but I don't see why this application should need any custom behavior. It is a normal application.
The application isn't reporting crash totals to match these numbers; it is a generally well liked 4/5 star app w/ few crashes.
Google Analytics measures duration as the time between interactions.
This means that in order to be able to measure duration, Google Analytics needs a minimum of two interactions to measure between. But they still need to collect data on one-interaction Sessions, and from the reporting perspective, every session starts the same - with an interaction. It's just that some don't go any further. To account for this, Google Analytics keeps a running total of Session duration.
When a user first interacts, that total is set to 0.
31 seconds later, they interact again. That total is updated to 31 seconds.
10 seconds later, they interact a third time. Total is now 41 seconds.
35 seconds later, they quit. This is not measurable, and hence not an interaction. Google Analytics waits faithfully for 30 minutes, before deciding that they aren't coming back.
Your total Session Duration is recorded as 41 seconds, as that was the last point at which you checked in. There's no way of knowing that you stuck around an extra 35 seconds.
This isn't an issue if you looked at 4 or 5 pages, but if you had only looked at 1 page, we would have been left with a Session Duration of 0. This is what happens with every 'Bounce'; every Session with only one interaction is measured '0' seconds long.
Throw into that a handful of people who interacted 8 or 9 seconds later, and you have an average of 1 second for the '0 - 10' category.
Turns out the problem was inside the Google Analytics SDK. A new version has been posted:
[Google Analytics SDK issue with short sessions][1]

Categories

Resources