Commit a87f4a2b authored by yogevbd's avatar yogevbd

Migrate GCM to FCM

parent 77f672cd
......@@ -20,8 +20,8 @@ android {
dependencies {
// Google's GCM.
compile 'com.google.android.gms:play-services-gcm:15.0.1'
// compile 'com.google.android.gms:play-services-gcm:15.0.1'
compile "com.google.firebase:firebase-messaging:17.3.0"
compile 'com.facebook.react:react-native:+'
testCompile 'junit:junit:4.12'
......
......@@ -21,39 +21,16 @@
-->
<service android:name=".core.ProxyService"/>
<!--
Google's ready-to-use GcmReceiver.
1. Awaits actual GCM messages (e.g. push notifications) and invokes the GCM service with the concrete content.
2. Awaits instance-ID/token refresh requests from the GCM and invokes the Instance-ID listener service.
-->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<!-- Dispatched by the GcmReceiver when messages are received. -->
<service
android:name="com.wix.reactnativenotifications.gcm.GcmMessageHandlerService"
android:exported="false">
android:name=".gcm.FcmInstanceIdListenerService">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- Dispatched by the GcmReceiver. Starts the designated refresh-handling service. -->
<service
android:name=".gcm.GcmInstanceIdListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name=".gcm.GcmInstanceIdRefreshHandlerService"
android:name=".gcm.FcmInstanceIdRefreshHandlerService"
android:exported="false" />
</application>
......
......@@ -23,7 +23,7 @@ import com.wix.reactnativenotifications.core.notification.PushNotification;
import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer;
import com.wix.reactnativenotifications.core.notificationdrawer.PushNotificationsDrawer;
import com.wix.reactnativenotifications.gcm.GcmInstanceIdRefreshHandlerService;
import com.wix.reactnativenotifications.gcm.FcmInstanceIdRefreshHandlerService;
import static com.wix.reactnativenotifications.Defs.LOGTAG;
......@@ -47,7 +47,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
@Override
public void initialize() {
Log.d(LOGTAG, "Native module init");
startGcmIntentService(GcmInstanceIdRefreshHandlerService.EXTRA_IS_APP_INIT);
startGcmIntentService(FcmInstanceIdRefreshHandlerService.EXTRA_IS_APP_INIT);
final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext());
notificationsDrawer.onAppInit();
......@@ -56,7 +56,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
@ReactMethod
public void refreshToken() {
Log.d(LOGTAG, "Native method invocation: refreshToken()");
startGcmIntentService(GcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH);
startGcmIntentService(FcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH);
}
@ReactMethod
......@@ -138,7 +138,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
protected void startGcmIntentService(String extraFlag) {
final Context appContext = getReactApplicationContext().getApplicationContext();
final Intent tokenFetchIntent = new Intent(appContext, GcmInstanceIdRefreshHandlerService.class);
final Intent tokenFetchIntent = new Intent(appContext, FcmInstanceIdRefreshHandlerService.class);
tokenFetchIntent.putExtra(extraFlag, true);
appContext.startService(tokenFetchIntent);
}
......
......@@ -3,16 +3,26 @@ package com.wix.reactnativenotifications.gcm;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.gcm.GcmListenerService;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import com.wix.reactnativenotifications.core.notification.IPushNotification;
import com.wix.reactnativenotifications.core.notification.PushNotification;
import java.util.Map;
import static com.wix.reactnativenotifications.Defs.LOGTAG;
public class GcmMessageHandlerService extends GcmListenerService {
/**
* Instance-ID + token refreshing handling service. Contacts the GCM to fetch the updated token.
*
* @author amitd
*/
public class FcmInstanceIdListenerService extends FirebaseMessagingService {
@Override
public void onMessageReceived(String s, Bundle bundle) {
public void onMessageReceived(RemoteMessage message){
Map data = message.getData();
Bundle bundle = convertMapToBundle(data);
Log.d(LOGTAG, "New message from GCM: " + bundle);
try {
......@@ -23,4 +33,14 @@ public class GcmMessageHandlerService extends GcmListenerService {
Log.v(LOGTAG, "GCM message handling aborted", e);
}
}
private Bundle convertMapToBundle(Map<String, String> map) {
Bundle bundle = new Bundle();
for (Map.Entry<String, String> entry : map.entrySet()) {
bundle.putString(entry.getKey(), entry.getValue());
}
return bundle;
}
}
......@@ -3,18 +3,18 @@ package com.wix.reactnativenotifications.gcm;
import android.app.IntentService;
import android.content.Intent;
public class GcmInstanceIdRefreshHandlerService extends IntentService {
public class FcmInstanceIdRefreshHandlerService extends IntentService {
public static String EXTRA_IS_APP_INIT = "isAppInit";
public static String EXTRA_MANUAL_REFRESH = "doManualRefresh";
public GcmInstanceIdRefreshHandlerService() {
super(GcmInstanceIdRefreshHandlerService.class.getSimpleName());
public FcmInstanceIdRefreshHandlerService() {
super(FcmInstanceIdRefreshHandlerService.class.getSimpleName());
}
@Override
protected void onHandleIntent(Intent intent) {
IGcmToken gcmToken = GcmToken.get(this);
IFcmToken gcmToken = FcmToken.get(this);
if (gcmToken == null) {
return;
}
......
package com.wix.reactnativenotifications.gcm;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;
import static com.wix.reactnativenotifications.Defs.GCM_SENDER_ID_ATTR_NAME;
import static com.wix.reactnativenotifications.Defs.LOGTAG;
import static com.wix.reactnativenotifications.Defs.TOKEN_RECEIVED_EVENT_NAME;
public class GcmToken implements IGcmToken {
public class FcmToken implements IFcmToken {
final protected Context mAppContext;
protected static String sToken;
protected GcmToken(Context appContext) {
protected FcmToken(Context appContext) {
if (!(appContext instanceof ReactApplication)) {
throw new IllegalStateException("Application instance isn't a react-application");
}
mAppContext = appContext;
}
public static IGcmToken get(Context context) {
public static IFcmToken get(Context context) {
Context appContext = context.getApplicationContext();
if (appContext instanceof INotificationsGcmApplication) {
return ((INotificationsGcmApplication) appContext).getGcmToken(context);
return ((INotificationsGcmApplication) appContext).getFcmToken(context);
}
return new GcmToken(appContext);
return new FcmToken(appContext);
}
@Override
......@@ -73,51 +70,14 @@ public class GcmToken implements IGcmToken {
}
protected void refreshToken() {
try {
sToken = getNewToken();
} catch (Exception e) {
Log.e(LOGTAG, "Failed to retrieve new token", e);
return;
}
sendTokenToJS();
}
@NonNull
protected String getNewToken() throws Exception {
final InstanceID instanceId = InstanceID.getInstance(mAppContext);
Log.d(LOGTAG, "GCM is refreshing token... instanceId=" + instanceId.getId());
// TODO why is this needed?
GoogleCloudMessaging.getInstance(mAppContext).close();
try {
final String registrationToken = instanceId.getToken(getSenderId(), GoogleCloudMessaging.INSTANCE_ID_SCOPE);
Log.i(LOGTAG, "GCM has a new token: instanceId=" + instanceId.getId() + ", token=" + registrationToken);
return registrationToken;
} catch (Exception e) {
throw new Exception("FATAL: Failed to fetch a fresh new token, instanceId=" + instanceId.getId(), e);
}
}
protected String getSenderId() {
final String senderId = getSenderIdFromManifest();
if (senderId == null) {
throw new IllegalStateException("Sender ID not found in manifest. Did you forget to add it as the value of a '"+GCM_SENDER_ID_ATTR_NAME+"' meta-data field?");
}
return senderId;
}
protected String getSenderIdFromManifest() {
final ApplicationInfo appInfo;
try {
appInfo = mAppContext.getPackageManager().getApplicationInfo(mAppContext.getPackageName(), PackageManager.GET_META_DATA);
return appInfo.metaData.getString(GCM_SENDER_ID_ATTR_NAME);
} catch (PackageManager.NameNotFoundException e) {
// Should REALLY never happen cause we're querying for our own package.
Log.e(LOGTAG, "Failed to resolve sender ID from manifest", e);
return null;
}
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
sToken = instanceIdResult.getToken();
Log.i(LOGTAG, "FCM has a new token" + "=" + sToken);
sendTokenToJS();
}
});
}
protected void sendTokenToJS() {
......
package com.wix.reactnativenotifications.gcm;
import android.content.Intent;
import com.google.android.gms.iid.InstanceIDListenerService;
/**
* Instance-ID + token refreshing handling service. Contacts the GCM to fetch the updated token.
*
* @author amitd
*/
public class GcmInstanceIdListenerService extends InstanceIDListenerService {
@Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
// Google recommends running this from an intent service.
Intent intent = new Intent(this, GcmInstanceIdRefreshHandlerService.class);
startService(intent);
}
}
package com.wix.reactnativenotifications.gcm;
public interface IGcmToken {
public interface IFcmToken {
/**
* Handle an event where we've been notified of a that a fresh token is now available from Google.
......
......@@ -3,5 +3,5 @@ package com.wix.reactnativenotifications.gcm;
import android.content.Context;
public interface INotificationsGcmApplication {
IGcmToken getGcmToken(Context context);
IFcmToken getFcmToken(Context context);
}
{
"name": "react-native-notifications",
"version": "1.1.23",
"version": "1.2.0",
"description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android",
"author": "Lidan Hifi <lidan.hifi@gmail.com>",
"license": "MIT",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment