Reading local Storage very slow in background (push notification trigger)


#1

Ionic 2 rc4
phonegap-plugin-push 1.9.2
Android 6.0

My app receives push notifications, the notification itself always arrives fine

The problem is that reading native storage inside the push.on(‘notification’…) runs very slow when the app is in the background, or sometimes it never revolves the storage.get promise. push.on gets triggered, but when it gets to storage.get(‘data’).then =>((data) … it takes 30 seconds or more (or never) to return data from the local storage when the app is in the background. When the app is in the foreground, it is instant.

There is no difference in the app for push notifications between foreground and background, but the difference in speed is huge when trying to read the local storage.

It does not matter if the screen is on or off, so it’s not a matter of the phone being asleep.

Is there something about the app being in the background that would make reading local storage (or promises) act differently?


#2

I could be completely wrong here, but I have a feeling since your running Android 6.0, it could be an effect due to Mashmallow’ Doze: https://developer.android.com/training/monitoring-device-state/doze-standby.html

Pay particular attention to:

Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window.

What could be happening in your case, is that your app is being ‘dozed’, and the background task is being bundled with other apps to be run at the next maintenance window, which could be 30 seconds, or longer. You should be able to test the state of doze using adb, as per the instructions in the link above.

A google search also pulled up the following: https://github.com/jessemonroy650/top-phonegap-mistakes/blob/master/android-doze.md

Android Doze

Date: 2015-11-27

Last Upate: 2016-03-01

New as of Android 6.0 (Marshmallow).

Official Blogs

> GCM has two priority types for messages, called high priority and normal priority. When using high priority, GCM attempts to deliver messages immediately, waking a device in Doze, as needed. (...) However, when using normal priority (the default priority), there are a number of different behaviors when the device is in Doze (...). 1. most important change is that messages will be batched (...) 2. We **discard** messages whose time_to_live expires while the device is in Doze (including TTL=0).
> *Battery* - We're making Android devices smarter about managing power through a new feature called **Doze**. With M, Android uses significant motion detection to learn if a device has been left unattended for a while. In this state, Android will exponentially back off background activity, trading off a little bit of app freshness for longer battery life. Consider how this may affect your app; for instance, if you're building a chat app, you may want to make use of high priority messages to wake your app when the device is dozing.
> Apps that attempt to bypass [system power management](https://developer.android.com/intl/en/training/monitoring-device-state/doze-standby.html) that are not [eligible for whitelisting](https://developer.android.com/intl/en/training/monitoring-device-state/doze-standby.html#whitelisting-cases).

Blogs Related

Articles Related

SO Post that alerted me to this

Known Devices with Related Issues

> The issue was with an [Xperia Z3](http://community.phonegap.com/nitobi/topics/background-location-that-works#reply_16808003) running [Android 5.1.1](http://community.phonegap.com/nitobi/topics/background-location-that-works#reply_16786544)

#3

I do not think it is the doze or standby mode causing it. Also, I am already using high priority messages.

The reason I do not think that it is doze is because the official documents state that doze is only enabled while on battery power, not when plugged in. I am not on battery power. Also, there is a setting in Settings -> Battery to disable doze on individual apps, which I disabled doze for my app, no change. Also, there is no issue with network communication between my app and my server during this time, and doze would affect the network communication if doze was being used. Only the native sql storage has the issue, not network.

Changing from native sql storage to using a temporary array (just changing the type in the data provider from the native to a local temporary array, and removing all the resolve parts of retrieving the data since an array does not use resolve) made everything work perfectly. Evidently, there is a problem with reading from native sql storage while the Android 6.0 app is in the background. Seems crazy, but simply changing to a different type of storage immediately fixed the problem.

So, instead of reading sql storage during background, I’m reading the temp array during background.


#4

Glad to hear you found a solution at least. That does sound very strange indeed, and the sort of thing that would be horribly time consuming to test/debug. It might even be worth creating an issue on the Ionic github if you think it’s an Ionic issue rather that your implementation.


#5

HI, how did You resolve this problem because I have the same problem. Can you post Your new code here or send me as a message please? I need to track changing in string that I saved in local storage, so if It changes, app needs to fire up a notification.