Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable compatibility with other Android GCM providers #166

Merged
merged 1 commit into from
Mar 30, 2017

Conversation

jtreanor
Copy link
Contributor

Since we built this plugin, there have been many instances of people experiencing issues with Android push notifications when using other push providers (such as phonegap-plugin-push, OneSignal or UrbanAirship). The cause of this has been that Android will only notify one GcmListenerService instance of incoming notifications. Here are some of the issues: https://github.com/intercom/intercom-cordova/issues/165, https://github.com/intercom/intercom-cordova/issues/164, https://github.com/intercom/intercom-cordova/issues/139, https://github.com/intercom/intercom-cordova/issues/19, https://github.com/intercom/intercom-cordova/issues/3 and phonegap/phonegap-plugin-push#1640.

The fix until now has been to fork phonegap-plugin-push. This is less than ideal and does not address the issue for other plugins.

These changes introduce IntercomIntentService which acts as an entry point for all com.google.android.c2dm.intent.RECEIVE intents. If the Intent is an Intercom notification, we handle it. Otherwise it is passed to the next highest priority service.

This change will stop the need to use a forked version of phonegap-plugin-push as well as allowing Intercom to work alongside other push plugins.

Note: this does not fix the issue for FCM. It may be possible to use a similar solution for that in the future.

@Override
protected void onHandleIntent(Intent intent) {
if (intercomPushClient.isIntercomPush(intent.getExtras())) {
intercomPushClient.handlePush(getApplication(), intent.getExtras());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we return; after this line and not have the else on the next line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@jtreanor jtreanor force-pushed the jtreanor/gcm_interoperability branch from 8e25bcc to 850c460 Compare March 30, 2017 16:12
Intent passThroughIntent = new Intent(intent);
passThroughIntent.setComponent(null);

List<ResolveInfo> services = getPackageManager().queryIntentServices(passThroughIntent, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's 0 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be the default value. Just checking the docs to confirm my understanding of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an @IntDef flag, so 0 means "no flags". (It is 0 because 0 | x == x).

@jtreanor jtreanor force-pushed the jtreanor/gcm_interoperability branch from 850c460 to 84d2fb2 Compare March 30, 2017 16:19
} catch (ClassNotFoundException e) {
// Class not found. Try the next service
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there something to be done here if there are services and none of them have been found?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. If there are no services there is nothing to be done (e.g. only Intercom is setup for push).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no services in the services list that's true, I'm wondering about the situation where that is not empty and we still exit the loop (i.e. an exception was thrown and caught in the loop)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed offline. The behaviour here is that if Class.forName() somehow fails, we will move on and try to pass to the next highest priority service.

}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any tests we could write for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not really. There isn't a way to run native Android tests for a Cordova plugin.

We could set up an Android project in the repo that includes this file (and others) so that they can be unit tested. Something to consider in the future perhaps.

@jtreanor jtreanor merged commit b2aaab9 into master Mar 30, 2017
@jtreanor jtreanor deleted the jtreanor/gcm_interoperability branch March 30, 2017 17:19
@jtreanor
Copy link
Contributor Author

Thanks everyone. I'll push a new release in the morning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants