Does onTokenRefresh get called on app update? - google-cloud-messaging

Does InstanceIDListenerService#onTokenRefresh get called in all cases where a gcm token may have changed, like when an app gets updated, or gets restored from an auto-backup, etc? Or do I still have to worry about catching those types of things like in older versions of GCM?

Related

How to queue requests in React Native without Redux?

Let's say I have a notes app. I want to enable the user to make changes while he is offline, save the changes optimistically in a Mobx store, and add a request to save the changes (on the server) to a queue.
Then when the internet connection is re-established I want to run the requests in the queue one by one so the data in the app syncs with data on the server.
Any suggestions would help.
I tried using react-native-job-queue but it doesn't seem to work.
I also considered react-native-queue but the library seems to be abandoned.
You could create a separate store (or an array in AsyncStorage) for pending operations, and add the operations to an array there when the network is disconnected. Tell your existing stores to look there for data, so you can render it optimistically. Then, when you detect a connection, run the updates in array order, and clear the array when done.
You could also use your existing stores, and add something like pending: true to values that haven't posted to your backend. However, you'll have less control over the order of operations, which sounds like it is important.
As it turns out I was in the wrong. The react-native-job-queue library does work, I just made a mistake by trying to pass a function reference (API call) to the Worker instead of just passing an object that contains the request URL and method and then just implement the Worker to make the API call based on those parameters.

GCM 3.0: New registration does not expire tokens registered with GCMRegistrar

We are switching our notifications infrastructure to use new GCM 3.0 registration mechanism using Instance ID API. Previously we were using old mechanism using GCMRegistrar.register() method.
The problem we have is that we have noticed that if device was registered with old GCMRegistrar, after update and registering with new Instance ID API, both registration tokens are valid and can receive notifications.
I expected old registration token to be deactivated and that our push server would receive canonical registration ID when sending notification to old token (as described here GCM registering with two different working registration ids), especially that application version has changed, but such case seems not to happen.
Is this correct behavior of GCM? Is there any way we can detect on push server that device received new token (without unregistering from app)?
I have finally received an answer from Google support regarding my issue. It turned out that this was intended behavior:
What you observed is in the intended behavior due to the need to support backward compatible
registration ID.
We recommend you to flag the old registration ID from gcmregistrar() and don't use that to send anymore once you have the registration token from getToken(). (I believe you probably has implemented a solution to detect such)
Our solution was to simply remove old registration tokens from our push server before registering new user.
We did not use GCMRegistrar.unregister() as we observed that it was able to unregister new tokens (obtained via getToken()).
UPDATE:
I just wanted to provide a quick update to anyone interested in this subject.
It seems that this issue was fixed as when we tested our registration mechanism recently, it turned out that new GCM tokens replace (and unregister) old tokens.
Registration token may change upon certain scenarios even going forward. While cononical registration ID is also a good idea. Use tokenRefresh as shown here as well.
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
Suggesting based on this line "it is needed for key rotation and to handle special cases" in method reference.

Worklight JSON Store, can we get race conditions?

Worklight 6.1 on both Windows (colleague) and Mac (me), building an a Hybrid app destined for Android device but to speed up development we do initial testing as Mobile Web App in Chrome browser on desktop.
We get a weird symptom that I'm trying to fine-down to a reproducible test case. I think I see different behaviours when stepping in debugger and just letting it run. Want to check whether a certain coding pattern could be the cause of the symptom before I go any further.
Fundamental question: should we wait for the resolution of a promise returned by a JSONSTore request for an action on a collection before issuing another request? more explanation below.
The overall intent is to load some data into the JSONStore, with some intelligent replace/merge action if a record is already present. Pseudo code:
for each record retrieved from back-end
if ( record already present in Store )
do some data merging
replace record
else
add record
The application code actually works like this, just considering the add() case, the problem manifests when the store is empty, all records need to be added
for each record to add
addPromise = store.get().add(record);
listOfPromises.insert(addPromise);
examine the list of promises recording any errors
That is there is no "wait" for add to finish before issuing the next add request. Hence in effect we've initiated a set of adds "in parallel" whatever that might mean in JavaScript in Chrome.
The code appears to run just fine, no errors reported. On android device it works reliably. In Chrome under normal running (no stepping in debugger) we end up with no reported errors but only one record inserted - indeed as though a snapshot of the initial "empty" store had been taken and each add is working on that "empty" copy.
After writing this I'm now pretty convinced that the coding pattern described above is vulnerable to a kind of race and that the better approach is build a list of documents to be added and insert them in a single operation.
A more detailed answer will be coming later, but I now know that this
the coding pattern described above is vulnerable to a kind of race and
that the better approach is build a list of documents to be added and
insert them in a single operation.
is true. In the browser the JSONStore does require that we wait for the result of one request before issuing another one. The recommended approach is
var dataToAdd = buildArrayOfDataToAdd(responseFromServer);
var dataToReplace = buildArrayOfDataToReplace(responseFromServer);
jsonstore.add( dataToAdd ).then( function() { jsonstore.replace( dataToReplace); })

Remove A URL Scheme Handler from Launch Services

I am developing a Cocoa Mac app which dynamically generates and registers itself for URL schemes. However, when the application registers itself to handle a newly generated URL scheme (e.g. myscheme1423://), I would like to prevent the application from responding to any previously registered URL schemes.
I am using LSSetDefaultHandlerForURLScheme() for the purpose of registering a URL scheme; in conjunction, the application automatically overwrites it's Info.plist to contain the new scheme. As you may know, the LSSetDefaultHandlerForURLScheme() function adds the given bundleID/scheme to a Launch Services database. However, I couldn't find an equivalent Launch Services function to remove the same bundleID/scheme pair from the database.
I know that I could simply ignore any external events which originated from a URL scheme other than the one for which the app is actively registered, but it feels to me that there should be a simple way to completely wipe out the system's knowledge of the previous scheme. If my application goes through the process of registering for a new scheme more than a few hundred times, a point will come where a significant amount of space (for a Plist, at least) is being taken up on disk by a plethora of pointless pieces of data (i.e. the old Launch Services entries).
I just fired up a playground and began playing. This is utterly undocumented but it appears to work.
Try passing ("None" as CFString) for the second parameter of
LSSetDefaultHandlerForURLScheme()

ALAsset invalid after Camera Roll changes?

I write some photos to the photo library using UIImageWriteToSavedPhotosAlbum() and at the same time I display the contents of this asset group (ALAssetsGroupSavedPhotos) using enumerateAssetsUsingBlock: and friends. Sometimes the assets returned by enumerating the group become sort of “invalid”, meaning that the defaultRepresentation call returns nil, although the asset is still in memory.
I noticed that this seems to happen after the photo library gets modified by the UIImageWriteToSavedPhotosAlbum() call. Is this a documented behaviour? How can I prevent it? Reloading the assets is not a feasible option, as the user might already be somewhere deeper in the UI working with the asset.
this is an unfortunate, but documented behavior. For reference:
"ALAssetsLibraryChangedNotification Sent when the contents of the
assets library have changed from under the app that is using the data.
When you receive this notification, you should discard any cached
information and query the assets library again. You should consider
invalid any ALAsset, ALAssetsGroup, or ALAssetRepresentation objects
you are referencing after finishing processing the notification."
So what you have to do is to register an observer for ALAssetsLibraryChangedNotification. (And there is a bug in regarding this notification on iOS 5.X, see Open Radar.)
When you receive the notification you have to reenumerate all groups and assets. There is at the moment no other way. This is very unfortunate from a GUI perspective and we can only hope Apple improves this mechanism in the future.
Cheers,
Hendrik