diff --git a/android/build.gradle b/android/build.gradle index de0db35f9d7c22a6d8a179f04fc39dafa1275214..2fdb45b1175a62a8df25a1d48d5d609484230472 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -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' diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 14334752383c271cef67a598c6282e09dcbd8885..ffef75f236e30d1e2d4b99280dcb04964b70afd9 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -21,39 +21,16 @@ --> - - - - - - - - - + android:name=".gcm.FcmInstanceIdListenerService"> - - - - - - - + + + diff --git a/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java b/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java index 33a13bf94c95b8070bcb9cdd65fcceefa1e8c2ce..6588ce058b013f2ee0a87eec381377f3752a11f2 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java +++ b/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java @@ -8,6 +8,7 @@ import android.os.Bundle; import android.support.v4.app.NotificationManagerCompat; import android.util.Log; +import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; @@ -23,20 +24,21 @@ 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 com.google.firebase.FirebaseApp; import static com.wix.reactnativenotifications.Defs.LOGTAG; -public class RNNotificationsModule extends ReactContextBaseJavaModule implements AppLifecycleFacade.AppVisibilityListener, Application.ActivityLifecycleCallbacks { +public class RNNotificationsModule extends ReactContextBaseJavaModule implements ActivityEventListener { public RNNotificationsModule(Application application, ReactApplicationContext reactContext) { super(reactContext); - if (AppLifecycleFacadeHolder.get() instanceof ReactAppLifecycleFacade) { ((ReactAppLifecycleFacade) AppLifecycleFacadeHolder.get()).init(reactContext); } - AppLifecycleFacadeHolder.get().addVisibilityListener(this); - application.registerActivityLifecycleCallbacks(this); + + reactContext.addActivityEventListener(this); } @Override @@ -47,16 +49,32 @@ 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(); } + @Override + public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { + + } + + @Override + public void onNewIntent(Intent intent) { + Bundle notificationData = intent.getExtras(); + if (notificationData != null) { + final IPushNotification notification = PushNotification.get(getReactApplicationContext().getApplicationContext(), notificationData); + if (notification != null) { + notification.onOpened(); + } + } + } + @ReactMethod public void refreshToken() { Log.d(LOGTAG, "Native method invocation: refreshToken()"); - startGcmIntentService(GcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH); + startGcmIntentService(FcmInstanceIdRefreshHandlerService.EXTRA_MANUAL_REFRESH); } @ReactMethod @@ -96,49 +114,9 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements promise.resolve(new Boolean(hasPermission)); } - @Override - public void onAppVisible() { - final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext()); - notificationsDrawer.onAppVisible(); - } - - @Override - public void onAppNotVisible() { - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(getReactApplicationContext().getApplicationContext()); - notificationsDrawer.onNewActivity(activity); - } - - @Override - public void onActivityStarted(Activity activity) { - } - - @Override - public void onActivityResumed(Activity activity) { - } - - @Override - public void onActivityPaused(Activity activity) { - } - - @Override - public void onActivityStopped(Activity activity) { - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle outState) { - } - - @Override - public void onActivityDestroyed(Activity activity) { - } - 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); } diff --git a/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java b/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java index 417e12b6417c2d4c40799c662047c0cd3f8e6402..d280fe7ebc6c2902fbc57e1f1308a583bfe67027 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java +++ b/android/src/main/java/com/wix/reactnativenotifications/RNNotificationsPackage.java @@ -1,22 +1,41 @@ package com.wix.reactnativenotifications; +import android.app.Activity; import android.app.Application; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; +import com.google.firebase.FirebaseApp; +import com.wix.reactnativenotifications.core.AppLifecycleFacade; +import com.wix.reactnativenotifications.core.AppLifecycleFacadeHolder; +import com.wix.reactnativenotifications.core.notification.IPushNotification; +import com.wix.reactnativenotifications.core.notification.PushNotification; +import com.wix.reactnativenotifications.core.notificationdrawer.IPushNotificationsDrawer; +import com.wix.reactnativenotifications.core.notificationdrawer.PushNotificationsDrawer; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; -public class RNNotificationsPackage implements ReactPackage { +import static com.wix.reactnativenotifications.Defs.LOGTAG; + +public class RNNotificationsPackage implements ReactPackage, AppLifecycleFacade.AppVisibilityListener, Application.ActivityLifecycleCallbacks { private final Application mApplication; public RNNotificationsPackage(Application application) { mApplication = application; + FirebaseApp.initializeApp(application.getApplicationContext()); + + AppLifecycleFacadeHolder.get().addVisibilityListener(this); + application.registerActivityLifecycleCallbacks(this); } @Override @@ -28,4 +47,55 @@ public class RNNotificationsPackage implements ReactPackage { public List createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } + + @Override + public void onAppVisible() { + final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(mApplication.getApplicationContext()); + notificationsDrawer.onAppVisible(); + } + + @Override + public void onAppNotVisible() { + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + final IPushNotificationsDrawer notificationsDrawer = PushNotificationsDrawer.get(mApplication.getApplicationContext()); + notificationsDrawer.onNewActivity(activity); + + Intent intent = activity.getIntent(); + if (intent != null) { + Bundle notificationData = intent.getExtras(); + if (notificationData != null) { + final IPushNotification pushNotification = PushNotification.get(mApplication.getApplicationContext(), notificationData); + if (pushNotification != null) { + pushNotification.onOpened(); + } + } + } + } + + @Override + public void onActivityStarted(Activity activity) { + } + + @Override + public void onActivityResumed(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + } + + @Override + public void onActivityStopped(Activity activity) { + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + } + + @Override + public void onActivityDestroyed(Activity activity) { + } } diff --git a/android/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java b/android/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java index 3ea5eb3d0527f734ffb89969939dacc210883794..ba5e1c3238f22000b3127ba53f9a54120a7b2b76 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java +++ b/android/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java @@ -43,6 +43,10 @@ public class PushNotification implements IPushNotification { }; public static IPushNotification get(Context context, Bundle bundle) { + if (verifyNotificationBundle(bundle) == false) { + return null; + } + Context appContext = context.getApplicationContext(); if (appContext instanceof INotificationsApplication) { return ((INotificationsApplication) appContext).getPushNotification(context, bundle, AppLifecycleFacadeHolder.get(), new AppLaunchHelper()); @@ -58,6 +62,14 @@ public class PushNotification implements IPushNotification { mNotificationProps = createProps(bundle); } + private static boolean verifyNotificationBundle(Bundle bundle) { + if (bundle.getString("google.message_id") != null) { + return true; + } + + return false; + } + @Override public void onReceived() throws InvalidNotificationException { postNotification(null); @@ -92,7 +104,6 @@ public class PushNotification implements IPushNotification { protected void digestNotification() { if (!mAppLifecycleFacade.isReactInitialized()) { setAsInitialNotification(); - launchOrResumeApp(); return; } @@ -122,10 +133,6 @@ public class PushNotification implements IPushNotification { protected void dispatchUponVisibility() { mAppLifecycleFacade.addVisibilityListener(getIntermediateAppVisibilityListener()); - - // Make the app visible so that we'll dispatch the notification opening when visibility changes to 'true' (see - // above listener registration). - launchOrResumeApp(); } protected AppVisibilityListener getIntermediateAppVisibilityListener() { @@ -197,9 +204,4 @@ public class PushNotification implements IPushNotification { private void notifyOpenedToJS() { mJsIOHelper.sendEventToJS(NOTIFICATION_OPENED_EVENT_NAME, mNotificationProps.asBundle(), mAppLifecycleFacade.getRunningReactContext()); } - - protected void launchOrResumeApp() { - final Intent intent = mAppLaunchHelper.getLaunchIntent(mContext); - mContext.startActivity(intent); - } } diff --git a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmMessageHandlerService.java b/android/src/main/java/com/wix/reactnativenotifications/gcm/FcmInstanceIdListenerService.java similarity index 63% rename from android/src/main/java/com/wix/reactnativenotifications/gcm/GcmMessageHandlerService.java rename to android/src/main/java/com/wix/reactnativenotifications/gcm/FcmInstanceIdListenerService.java index f59665529429b87779fc37fe009f7505b30bc394..2456913ea09c931e99aa29550c9a61ac0c07c237 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmMessageHandlerService.java +++ b/android/src/main/java/com/wix/reactnativenotifications/gcm/FcmInstanceIdListenerService.java @@ -3,16 +3,25 @@ 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){ + Bundle bundle = message.toIntent().getExtras(); Log.d(LOGTAG, "New message from GCM: " + bundle); try { diff --git a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmInstanceIdRefreshHandlerService.java b/android/src/main/java/com/wix/reactnativenotifications/gcm/FcmInstanceIdRefreshHandlerService.java similarity index 74% rename from android/src/main/java/com/wix/reactnativenotifications/gcm/GcmInstanceIdRefreshHandlerService.java rename to android/src/main/java/com/wix/reactnativenotifications/gcm/FcmInstanceIdRefreshHandlerService.java index 3aa7aa9dc8e248d2fa10ef93f3b296ec158e9b93..8270ad68e724f6463bee122fb17462c0a6a18adb 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmInstanceIdRefreshHandlerService.java +++ b/android/src/main/java/com/wix/reactnativenotifications/gcm/FcmInstanceIdRefreshHandlerService.java @@ -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; } diff --git a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmToken.java b/android/src/main/java/com/wix/reactnativenotifications/gcm/FcmToken.java similarity index 51% rename from android/src/main/java/com/wix/reactnativenotifications/gcm/GcmToken.java rename to android/src/main/java/com/wix/reactnativenotifications/gcm/FcmToken.java index b11a6b5f4a6a89342d5d684bd0ed2d7950ec5991..44c8ec6dffe65f122ad21a4f51c2438fd2f11a31 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmToken.java +++ b/android/src/main/java/com/wix/reactnativenotifications/gcm/FcmToken.java @@ -1,41 +1,38 @@ 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() { + @Override + public void onSuccess(InstanceIdResult instanceIdResult) { + sToken = instanceIdResult.getToken(); + Log.i(LOGTAG, "FCM has a new token" + "=" + sToken); + sendTokenToJS(); + } + }); } protected void sendTokenToJS() { diff --git a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmInstanceIdListenerService.java b/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmInstanceIdListenerService.java deleted file mode 100644 index 933415f5cdc3b96b055c2a5e1c76208e914dc9b6..0000000000000000000000000000000000000000 --- a/android/src/main/java/com/wix/reactnativenotifications/gcm/GcmInstanceIdListenerService.java +++ /dev/null @@ -1,21 +0,0 @@ -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); - } -} diff --git a/android/src/main/java/com/wix/reactnativenotifications/gcm/IGcmToken.java b/android/src/main/java/com/wix/reactnativenotifications/gcm/IFcmToken.java similarity index 95% rename from android/src/main/java/com/wix/reactnativenotifications/gcm/IGcmToken.java rename to android/src/main/java/com/wix/reactnativenotifications/gcm/IFcmToken.java index f324a591f64f0324be8132d41243c18b7b12f60f..9e75d39014c1a21bce7f854a3e0aa2d97abeaf0c 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/gcm/IGcmToken.java +++ b/android/src/main/java/com/wix/reactnativenotifications/gcm/IFcmToken.java @@ -1,6 +1,6 @@ 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. diff --git a/android/src/main/java/com/wix/reactnativenotifications/gcm/INotificationsGcmApplication.java b/android/src/main/java/com/wix/reactnativenotifications/gcm/INotificationsGcmApplication.java index 36f59f71cf2e4682d409c1fd21ac07a333d66a11..d318ecc4a9e1b78c99ce43875459c5d841426ad5 100644 --- a/android/src/main/java/com/wix/reactnativenotifications/gcm/INotificationsGcmApplication.java +++ b/android/src/main/java/com/wix/reactnativenotifications/gcm/INotificationsGcmApplication.java @@ -3,5 +3,5 @@ package com.wix.reactnativenotifications.gcm; import android.content.Context; public interface INotificationsGcmApplication { - IGcmToken getGcmToken(Context context); + IFcmToken getFcmToken(Context context); } diff --git a/package.json b/package.json index c070d13f5e4ba8f6461ce76379d92b45ac880712..4f3b9577e0668d25257a7ef5549305352a430117 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-notifications", - "version": "1.1.24", + "version": "1.2.52", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT",