Commit a87f4a2b authored by yogevbd's avatar yogevbd

Migrate GCM to FCM

parent 77f672cd
...@@ -20,8 +20,8 @@ android { ...@@ -20,8 +20,8 @@ android {
dependencies { dependencies {
// Google's GCM. // 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:+' compile 'com.facebook.react:react-native:+'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
......
...@@ -21,39 +21,16 @@ ...@@ -21,39 +21,16 @@
--> -->
<service android:name=".core.ProxyService"/> <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 <service
android:name="com.wix.reactnativenotifications.gcm.GcmMessageHandlerService" android:name=".gcm.FcmInstanceIdListenerService">
android:exported="false">
<intent-filter> <intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</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" />
</intent-filter> </intent-filter>
</service> </service>
<service <service
android:name=".gcm.GcmInstanceIdRefreshHandlerService" android:name=".gcm.FcmInstanceIdRefreshHandlerService"
android:exported="false" /> android:exported="false" />
</application> </application>
......
...@@ -23,7 +23,7 @@ import com.wix.reactnativenotifications.core.notification.PushNotification; ...@@ -23,7 +23,7 @@ import com.wix.reactnativenotifications.core.notification.PushNotification;
import com.wix.reactnativenotifications.core.notification.PushNotificationProps; import com.wix.reactnativenotifications.core.notification.PushNotificationProps;
import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer; import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer;
import com.wix.reactnativenotifications.core.notificationdrawer.PushNotificationsDrawer; 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; import static com.wix.reactnativenotifications.Defs.LOGTAG;
...@@ -47,7 +47,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements ...@@ -47,7 +47,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
@Override @Override
public void initialize() { public void initialize() {
Log.d(LOGTAG, "Native module init"); 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()); final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext());
notificationsDrawer.onAppInit(); notificationsDrawer.onAppInit();
...@@ -56,7 +56,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements ...@@ -56,7 +56,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
@ReactMethod @ReactMethod
public void refreshToken() { public void refreshToken() {
Log.d(LOGTAG, "Native method invocation: refreshToken()"); Log.d(LOGTAG, "Native method invocation: refreshToken()");
startGcmIntentService(GcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH); startGcmIntentService(FcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH);
} }
@ReactMethod @ReactMethod
...@@ -138,7 +138,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements ...@@ -138,7 +138,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements
protected void startGcmIntentService(String extraFlag) { protected void startGcmIntentService(String extraFlag) {
final Context appContext = getReactApplicationContext().getApplicationContext(); 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); tokenFetchIntent.putExtra(extraFlag, true);
appContext.startService(tokenFetchIntent); appContext.startService(tokenFetchIntent);
} }
......
...@@ -3,16 +3,26 @@ package com.wix.reactnativenotifications.gcm; ...@@ -3,16 +3,26 @@ package com.wix.reactnativenotifications.gcm;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; 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.IPushNotification;
import com.wix.reactnativenotifications.core.notification.PushNotification; import com.wix.reactnativenotifications.core.notification.PushNotification;
import java.util.Map;
import static com.wix.reactnativenotifications.Defs.LOGTAG; 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 @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); Log.d(LOGTAG, "New message from GCM: " + bundle);
try { try {
...@@ -23,4 +33,14 @@ public class GcmMessageHandlerService extends GcmListenerService { ...@@ -23,4 +33,14 @@ public class GcmMessageHandlerService extends GcmListenerService {
Log.v(LOGTAG, "GCM message handling aborted", e); 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; ...@@ -3,18 +3,18 @@ package com.wix.reactnativenotifications.gcm;
import android.app.IntentService; import android.app.IntentService;
import android.content.Intent; 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_IS_APP_INIT = "isAppInit";
public static String EXTRA_MANUAL_REFRESH = "doManualRefresh"; public static String EXTRA_MANUAL_REFRESH = "doManualRefresh";
public GcmInstanceIdRefreshHandlerService() { public FcmInstanceIdRefreshHandlerService() {
super(GcmInstanceIdRefreshHandlerService.class.getSimpleName()); super(FcmInstanceIdRefreshHandlerService.class.getSimpleName());
} }
@Override @Override
protected void onHandleIntent(Intent intent) { protected void onHandleIntent(Intent intent) {
IGcmToken gcmToken = GcmToken.get(this); IFcmToken gcmToken = FcmToken.get(this);
if (gcmToken == null) { if (gcmToken == null) {
return; return;
} }
......
package com.wix.reactnativenotifications.gcm; package com.wix.reactnativenotifications.gcm;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import com.facebook.react.ReactApplication; import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.iid.InstanceID; 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.LOGTAG;
import static com.wix.reactnativenotifications.Defs.TOKEN_RECEIVED_EVENT_NAME; import static com.wix.reactnativenotifications.Defs.TOKEN_RECEIVED_EVENT_NAME;
public class GcmToken implements IGcmToken { public class FcmToken implements IFcmToken {
final protected Context mAppContext; final protected Context mAppContext;
protected static String sToken; protected static String sToken;
protected GcmToken(Context appContext) { protected FcmToken(Context appContext) {
if (!(appContext instanceof ReactApplication)) { if (!(appContext instanceof ReactApplication)) {
throw new IllegalStateException("Application instance isn't a react-application"); throw new IllegalStateException("Application instance isn't a react-application");
} }
mAppContext = appContext; mAppContext = appContext;
} }
public static IGcmToken get(Context context) { public static IFcmToken get(Context context) {
Context appContext = context.getApplicationContext(); Context appContext = context.getApplicationContext();
if (appContext instanceof INotificationsGcmApplication) { if (appContext instanceof INotificationsGcmApplication) {
return ((INotificationsGcmApplication) appContext).getGcmToken(context); return ((INotificationsGcmApplication) appContext).getFcmToken(context);
} }
return new GcmToken(appContext); return new FcmToken(appContext);
} }
@Override @Override
...@@ -73,51 +70,14 @@ public class GcmToken implements IGcmToken { ...@@ -73,51 +70,14 @@ public class GcmToken implements IGcmToken {
} }
protected void refreshToken() { protected void refreshToken() {
try { FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( new OnSuccessListener<InstanceIdResult>() {
sToken = getNewToken(); @Override
} catch (Exception e) { public void onSuccess(InstanceIdResult instanceIdResult) {
Log.e(LOGTAG, "Failed to retrieve new token", e); sToken = instanceIdResult.getToken();
return; Log.i(LOGTAG, "FCM has a new token" + "=" + sToken);
}
sendTokenToJS(); 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;
}
} }
protected void 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; 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. * 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; ...@@ -3,5 +3,5 @@ package com.wix.reactnativenotifications.gcm;
import android.content.Context; import android.content.Context;
public interface INotificationsGcmApplication { public interface INotificationsGcmApplication {
IGcmToken getGcmToken(Context context); IFcmToken getFcmToken(Context context);
} }
{ {
"name": "react-native-notifications", "name": "react-native-notifications",
"version": "1.1.23", "version": "1.2.0",
"description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android",
"author": "Lidan Hifi <lidan.hifi@gmail.com>", "author": "Lidan Hifi <lidan.hifi@gmail.com>",
"license": "MIT", "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