customerio / customerio-reactnative

MIT License
25 stars 13 forks source link

Rich push notifications are not sending on Android #87

Closed lucasbeatdapp closed 1 year ago

lucasbeatdapp commented 1 year ago

SDK version: "customerio-reactnative": "^2.0.1"

Environment: development

Describe the bug Rich push notifications are not sending to my test Android physical device but regular notifications are ok. When I

To Reproduce Set up Rich push notifications on android using the CustomerIO react native documentation for FCM on android

Expected behavior I expect to be able to send push notifications to my android device. I am using the customerIO push notification tool to build the rich notification, when I have just a title and message in the notification it sends perfectly to the device, but as soon as I add an image, deep link, or both, the notification will not send.

Maybe I made mistake in setting up rich push notifications on my end but the steps seems a lot easier than IOS to set up and the rich push notifications work well on IOS

If there's any assistance or if this problem has been solved before, any information would be extremely appreciated!

mrehan27 commented 1 year ago

Hi @lucasbeatdapp Sorry to hear about the issue you are facing. If you are able to receive normal notifications, then you have setup push notifications correctly. Can you please answer the following so we can reproduce and identify the issue?

lucasbeatdapp commented 1 year ago

@mrehan27 Thank you for your reply!

When I send notifications in both an closed and killed state the behaviour is the same. Sends every time and I can open the notifications:

Screenshot 2023-02-07 at 11 24 44 AM

Does not send at all (Same behaviour if the image has anything in it:

Screenshot 2023-02-07 at 11 26 46 AM

The preview shows that there is no errors and when I click to send to a testing device it always says that the send is successful from the dashboard, but it is not appearing on the device. As soon as it's removed it works.

Looking through some of the logs in Logcat there isn't a lot that I can interpret from it but will post some of the error looking logs in here:

2023-02-07 11:39:14.937 667-11899/? E/ResolverController: No valid NAT64 prefix (601, <unspecified>/0)
2023-02-07 11:39:14.939 1509-1970/? E/NetdEventListenerService: handleMessage: { when=0 what=10001 obj=com.android.server.connectivity.NetdEventListenerService$DnsResultParams@521a284 target=com.android.server.connectivity.NetdEventListenerService$DnsEventHandler }
2023-02-07 11:39:16.969 667-1140/? E/Netd: getNetworkForDns: getNetId from enterpriseCtrl is netid 0
2023-02-07 11:40:38.606 647-647/? E/audit: type=1400 audit(1675798838.591:5275): avc:  denied  { kill } for  pid=0 comm="swapper/4" capability=5  scontext=u:r:kernel:s0 tcontext=u:r:kernel:s0 tclass=capability permissive=0 SEPF_SM-A115A_10_1021 audit_filtered

When I send a rich push notification that sends from the dashboard but doesn't show on the device this message pops in the logs

2023-02-07 11:43:09.915 1509-1940/? D/ConnectivityService: RoamNetwork. Ignore reportNetworkConnectivity for Wi-Fi network
2023-02-07 11:43:09.916 1509-3663/? D/SamsungAlarmManager: Cancel Alarm calling from uid:10188 pid :16996 / op:PendingIntent{897b356: PendingIntentRecord{7f228a2 com.google.android.gms broadcastIntent}}
2023-02-07 11:43:09.918 1509-3663/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T115332, SetElapsed=90078615, nowELAPSED=89455740
2023-02-07 11:43:09.918 1509-3663/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T114331, SetElapsed=89477501, nowELAPSED=89455740
2023-02-07 11:43:09.918 16996-12191/? I/AlarmManager: setExactAndAllowWhileIdle [name: GCM_HB_ALARM type: 2 triggerAtMillis: 91185741]
2023-02-07 11:43:09.922 1509-3663/? D/SamsungAlarmManager: setExact Intent (T:2/F:5/AC:false) 20230207T121159 - CU:10188/CP:16996
2023-02-07 11:43:09.922 1509-3663/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T115332, SetElapsed=90078615, nowELAPSED=89455744
2023-02-07 11:43:09.922 1509-3663/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T114331, SetElapsed=89477501, nowELAPSED=89455744
2023-02-07 11:43:09.937 16996-11701/? I/AlarmManager: setExactAndAllowWhileIdle [name: FcmRetry type: 2 triggerAtMillis: 89575758]
2023-02-07 11:43:09.940 1509-3663/? D/SamsungAlarmManager: setExact Intent (T:2/F:5/AC:false) 20230207T114509 - CU:10188/CP:16996
2023-02-07 11:43:09.940 1509-3663/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T114509, SetElapsed=89575758, nowELAPSED=89455762
2023-02-07 11:43:09.940 1509-3663/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T114331, SetElapsed=89477501, nowELAPSED=89455762
2023-02-07 11:43:09.949 10587-10587/com.app D/RNFirebaseMsgReceiver: broadcast received for message
2023-02-07 11:43:09.969 10587-10927/com.app W/ReactNativeJS: No background message handler has been set. Set a handler via the "setBackgroundMessageHandler" method.
2023-02-07 11:43:09.985 1509-2206/? D/SamsungAlarmManager: Cancel Alarm calling from uid:10188 pid :16996 / op:PendingIntent{b86c530: PendingIntentRecord{45df577 com.google.android.gms broadcastIntent}}
2023-02-07 11:43:09.987 1509-2206/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T115332, SetElapsed=90078615, nowELAPSED=89455809
2023-02-07 11:43:09.987 1509-2206/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T114331, SetElapsed=89477501, nowELAPSED=89455809
2023-02-07 11:43:10.228 667-1140/? D/EnterpriseController: netId is 0
lucasbeatdapp commented 1 year ago

I get this error to pop up when sending a rich push notification through to my android app when my app is fully closed. The payload had a title, message and deep link in it.

2023-02-07 12:05:30.203 1509-3668/? D/SamsungAlarmManager: Cancel Alarm calling from uid:10188 pid :16996 / op:PendingIntent{d334af9: PendingIntentRecord{7f228a2 com.google.android.gms broadcastIntent}}
2023-02-07 12:05:30.205 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T120622, SetElapsed=90847897, nowELAPSED=90796027
2023-02-07 12:05:30.205 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T120600, SetElapsed=90825822, nowELAPSED=90796027
2023-02-07 12:05:30.206 16996-18852/? I/AlarmManager: setExactAndAllowWhileIdle [name: GCM_HB_ALARM type: 2 triggerAtMillis: 92526028]
2023-02-07 12:05:30.209 1509-3668/? D/SamsungAlarmManager: setExact Intent (T:2/F:5/AC:false) 20230207T123420 - CU:10188/CP:16996
2023-02-07 12:05:30.209 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T120622, SetElapsed=90847897, nowELAPSED=90796031
2023-02-07 12:05:30.209 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T120559, SetElapsed=90825822, nowELAPSED=90796032
2023-02-07 12:05:30.223 16996-17502/? I/AlarmManager: setExactAndAllowWhileIdle [name: FcmRetry type: 2 triggerAtMillis: 90916043]
2023-02-07 12:05:30.225 1509-3668/? D/SamsungAlarmManager: setExact Intent (T:2/F:5/AC:false) 20230207T120730 - CU:10188/CP:16996
2023-02-07 12:05:30.225 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T120622, SetElapsed=90847897, nowELAPSED=90796047
2023-02-07 12:05:30.225 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T120559, SetElapsed=90825822, nowELAPSED=90796048
2023-02-07 12:05:30.234 18730-18730/com.app D/RNFirebaseMsgReceiver: broadcast received for message
2023-02-07 12:05:30.237 1509-3668/? W/ActivityManager: Background start not allowed: service Intent { cmp=com.app/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService (has extras) } to comapp/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService from pid=18730 uid=10242 pkg=com.app startFg?=false
2023-02-07 12:05:30.239 18730-18730/com.app E/RNFirebaseMsgReceiver: Background messages only work if the message priority is set to 'high'
    java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.app/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService (has extras) }: app is in background uid UidRecord{b0f73f5 u0a242 RCVR idle change:uncached procs:1 seq(0,0,0)}
        at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1688)
        at android.app.ContextImpl.startService(ContextImpl.java:1633)
        at android.content.ContextWrapper.startService(ContextWrapper.java:683)
        at android.content.ContextWrapper.startService(ContextWrapper.java:683)
        at io.invertase.firebase.messaging.ReactNativeFirebaseMessagingReceiver.onReceive(ReactNativeFirebaseMessagingReceiver.java:53)
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:4198)
        at android.app.ActivityThread.access$1600(ActivityThread.java:273)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2107)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8107)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
2023-02-07 12:05:30.260 1509-3668/? D/SamsungAlarmManager: Cancel Alarm calling from uid:10188 pid :16996 / op:PendingIntent{9927c4a: PendingIntentRecord{90a10d5 com.google.android.gms broadcastIntent}}
2023-02-07 12:05:30.262 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:2 / 20230207T120622, SetElapsed=90847897, nowELAPSED=90796084
2023-02-07 12:05:30.262 1509-3668/? I/SamsungAlarmManager: setLocked to kernel - T:3 / 20230207T120600, SetElapsed=90825822, nowELAPSED=90796084
2023-02-07 12:05:30.362 2064-2064/? D/SecStatusBarWifiView: updateState: WifiIconState(resId=2131232714, visible=true, activityId=2131232720)
2023-02-07 12:05:30.364 2064-2470/? D/Tile.WifiTile: handleUpdateState isTransient=false transientEnabling =false cb.isTransient=false state.state = 2 mStateBeforeClick.value =false enabled =true
2023-02-07 12:05:30.538 667-1140/? D/EnterpriseController: netId is 0
mrehan27 commented 1 year ago

Thanks for sharing this @lucasbeatdapp. Appreciate the details.

I see your app has react native firebase integrated as well. Unfortunately, we currently do not support integration with multiple notification services because Android OS will only chose one notification receiver at a time. But we are aware of the challenges and this is already in discussion. I'll add your vote to the issue so you're notified when it is available.

Meanwhile, if you want to make rich push notifications work, you can either use custom payload temporarily, or will have to remove react native firebase from your project till we roll out the support.

lucasbeatdapp commented 1 year ago

@mrehan27 Thank you for this information! I would recommend that this is highlighted within the documentation for the react native SDK as I believe this is something that needs to be known before/during the implementation of the SDK. I will test out the custom payload for now and consider options in terms of removing React native firebase.

lucasbeatdapp commented 1 year ago

@mrehan27 To be clear, if we were to remove React native Firebase messaging as a notification service would we be able to keep the remaining react native firebase SDK products on our app? Or would we need to remove react native firebase as a whole?

mrehan27 commented 1 year ago

Thanks for the suggestion @lucasbeatdapp. We'll consider this and update our docs soon.

For your question, you only need to remove notification service and can keep rest of the products.

lucasbeatdapp commented 1 year ago

@mrehan27 Amazing thanks! So right now I am working on removing react-native-firebase/messaging from our application so that we can send data-notifications on android OS.

But, I'm running into an issue on IOS again now where device tokens are only added on on app install. Previously, I was using the react-native-firebase/message to get the device tokens so that I could use the new feature in cio react native 2.0.1:

const token = ~value gotten through firebase messaging npm package~
CustomerIO.registerDeviceToken(token)

I'm wondering if you have any recommendations on what I can use to get a device token in my javascript code so that I can remove react-native-firebase/messaging without compromising the ability to add device tokens to an IOS users when the app is already installed.

Shahroz16 commented 1 year ago

Hey @lucasbeatdapp, can you share your AppDelegate file from iOS? feel free to retract any proprietary code information, just need to see how you are requesting for the token in their and if we could tweak something there to solve your usecase.

lucasbeatdapp commented 1 year ago

This is my AppDelegate most of which was auto generated by npx create-expo-app --template bare-minimum

#import <Firebase.h>
#import "AppDelegate.h"
#import "ExpoModulesCore-Swift.h"
#import "MyApp-Swift.h"
#import <FirebaseCore.h>

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#import <React/RCTConvert.h>

#import <React/RCTAppSetupUtils.h>

#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>

#import <react/config/ReactNativeConfig.h>

static NSString *const kRNConcurrentRoot = @"concurrentRoot";

@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
  RCTTurboModuleManager *_turboModuleManager;
  RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
  std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
  facebook::react::ContextContainer::Shared _contextContainer;
}
@end
#endif

@implementation AppDelegate

NotificationHandler* pnHandlerObj = [[NotificationHandler alloc] init];

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   // Configure Firebase
 [FIRApp configure];
 // Set FCM messaging delegate
 [FIRMessaging messaging].delegate = self;
  // Call this before  calling registerPushNotification:self
 [pnHandlerObj initializeCioSdk];
 // Register for remote push when the app starts 
 [pnHandlerObj registerPushNotification:self];
  RCTAppSetupPrepareApp(application);

  RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];

#if RCT_NEW_ARCH_ENABLED
  _contextContainer = std::make_shared<facebook::react::ContextContainer const>();
  _reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
  _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
  _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
  bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif

  NSDictionary *initProps = [self prepareInitialProps];
  UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:initProps];

  rootView.backgroundColor = [UIColor whiteColor];
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [self.reactDelegate createRootViewController];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  [super application:application didFinishLaunchingWithOptions:launchOptions];

  return YES;
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
  // If you'd like to export some custom RCTBridgeModules, add them here!
  return @[];
}

/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
  // Switch this bool to turn on and off the concurrent root
  return true;
}

- (NSDictionary *)prepareInitialProps
{
  NSMutableDictionary *initProps = [NSMutableDictionary new];
#if RCT_NEW_ARCH_ENABLED
  initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);
#endif
  return initProps;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
}

// Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
  BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
  return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
}

// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
}

// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
[pnHandlerObj didReceiveRegistrationToken:messaging fcmToken: fcmToken];
}

 //To show a notification when the app is in foreground
 -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
 {
     completionHandler( UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);
 }

#if RCT_NEW_ARCH_ENABLED

#pragma mark - RCTCxxBridgeDelegate

- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
  _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
                                                             delegate:self
                                                            jsInvoker:bridge.jsCallInvoker];
  return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
}

#pragma mark RCTTurboModuleManagerDelegate

- (Class)getModuleClassFromName:(const char *)name
{
  return RCTCoreModulesClassProvider(name);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
                                                      jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
  return nullptr;
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
                                                     initParams:
                                                         (const facebook::react::ObjCTurboModule::InitParams &)params
{
  return nullptr;
}

- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
  return RCTAppSetupDefaultModuleFromClass(moduleClass);
}

#endif

@end
Shahroz16 commented 1 year ago

Thanks, @lucasbeatdapp ! with expo it gets a bit hard since the files are auto-generated. But we are working on adding the ability in iOS to ask for permission later in the app state.

Shahroz16 commented 1 year ago

@lucasbeatdapp while we wait for the feature mentioned above, I wanted to check in on a workaround and see if that will work for you.

So when you add react-native-firebase/message, it overrides the firebase service used in customerio-reactnative SDK. Can you try adding the following lines of code in your Manifest.xml file in android?

This might override the service being used in react-native-firebase/message and get the push working.

lucasbeatdapp commented 1 year ago

@Shahroz16 Thank you! I tried this out today. To test this out, I made sure I have react-native-firebase messaging back in, add new lines of code to the Manifest.xml. I completed this and still got a similar error message in logcat.

E/RNFirebaseMsgReceiver: Background messages only work if the message priority is set to 'high'
    java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.myapp/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService (has extras) }: app is in background uid UidRecord{654f8c9 u0a251 RCVR bg:+1m19s446ms idle change:uncached procs:1 seq(0,0,0)}
        at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1688)
        at android.app.ContextImpl.startService(ContextImpl.java:1633)
        at android.content.ContextWrapper.startService(ContextWrapper.java:683)
        at android.content.ContextWrapper.startService(ContextWrapper.java:683)
        at io.invertase.firebase.messaging.ReactNativeFirebaseMessagingReceiver.onReceive(ReactNativeFirebaseMessagingReceiver.java:53)
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:4198)
        at android.app.ActivityThread.access$1600(ActivityThread.java:273)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2107)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:8107)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

My Manifest file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myeapp">

  <uses-permission android:name="android.permission.INTERNET" />
  <!-- OPTIONAL PERMISSIONS, REMOVE WHATEVER YOU DO NOT NEED -->
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-permission android:name="android.permission.VIBRATE" />
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
  <!-- These require runtime permissions on M -->
  <uses-permission android:name="android.permission.CAMERA" />

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

  <uses-permission android:name="android.permission.READ_CONTACTS" />
  <uses-permission android:name="android.permission.WRITE_CONTACTS" />

  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <!--  This permission is needed for Singular to retrieve Google Play Referrer data  -->
  <uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
  <!--  This permission is needed for Singular to retrieve data from the google licensing API  -->
  <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
  <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
  <!-- END OPTIONAL PERMISSIONS -->

  <queries>
    <!-- Support checking for http(s) links via the Linking API -->
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" />
    </intent>
  </queries>
<application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
    <service
      android:name=".CustomerIOFirebaseMessagingService"
      android:exported="false">
      <intent-filter android:priority="-1">
          <action android:name="com.google.firebase.MESSAGING_EVENT" />
      </intent-filter>
    </service>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="YOUR-APP-URL-HERE"/>
    <meta-data android:name="expo.modules.updates.EXPO_SDK_VERSION" android:value="YOUR-APP-SDK-VERSION-HERE"/>
    <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/AppTheme" android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <!-- Ensure you have these action/categories in your filter -->
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- This is the actual URI scheme -->
        <data android:scheme="myapp://" />
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
    <activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity" android:theme="@style/Base.Theme.AppCompat"></activity>
  </application>
  </manifest>
Shahroz16 commented 1 year ago

@lucasbeatdapp apologies, I should have been more clear. 😵‍💫 The link was supposed to be an idea it didn't have the correct path. Can you use this?

<service
    android:name="io.customer.messagingpush.CustomerIOFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

We tried it on our end and it seems to be working, but would love to know if it resolved your issue as well.

lucasbeatdapp commented 1 year ago

@Shahroz16 Thank you so much! So notifications are sending through properly for the most part, now I'm able to send rich push notis with at least the deep link, but it's inconsistent with send through images.

A message I'm seeing quite frequently in logcat while testing this out has something to do with the delivery id being sent:

2023-02-24 11:51:02.958 17929-19381 [CIO]                   com.myapp                   E  
4xx HTTP status code response. Probably a bug? {
 "meta": {
    "errors": [
     "malformed delivery id: ."
    ]
   }
 }

AND I'm still seeing this error:

Background messages only work if the message priority is set to 'high'
   java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.myapp/io.invertase.firebase.messaging.ReactNativeFirebaseMessagingHeadlessService (has extras) }: app is in background uid UidRecord{878917e u0a272 RCVR idle change:idle|uncached procs:1 seq(0,0,0)}
    at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1688)
    at android.app.ContextImpl.startService(ContextImpl.java:1633)
    at android.content.ContextWrapper.startService(ContextWrapper.java:683)
    at android.content.ContextWrapper.startService(ContextWrapper.java:683)
    at io.invertase.firebase.messaging.ReactNativeFirebaseMessagingReceiver.onReceive(ReactNativeFirebaseMessagingReceiver.java:53)
    at android.app.ActivityThread.handleReceiver(ActivityThread.java:4198)
    at android.app.ActivityThread.access$1600(ActivityThread.java:273)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2107)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:237)
    at android.app.ActivityThread.main(ActivityThread.java:8107)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)

but before I see this ^, a log comes before that saying broadcast received for message which wasn't happening before.

So in conclusion, notifications are sending through now but inconsistently in terms of timing often seeing this message Service took too long to process intent: com.google.android.c2dm.intent.RECEIVE Releasing WakeLock. which I'm assuming is related to delayed messages (This is not a problem). And I'm also seeing a log that's describing malformed delivery ids which I is probably related to me not being able to see notification data in my javascript when I open the app with a notificaition.

Thanks for continuing to help me with this problem!

Shahroz16 commented 1 year ago

That is great news @lucasbeatdapp !!

4xx HTTP status code response. Probably a bug? {
 "meta": {
    "errors": [
     "malformed delivery id: ."
    ]
   }
 }

This error that you see is because of the fact you are sending a test push, most probably. Since test push is not part of any campaign or broadcast, they don't have any delivery id.

The other warning is from the FCM library, you can ignore them, it's because of the fact your app is now using our service.

Can you paste the link to the images you are trying to send? I'll try them on my end and will see if I can replicate the timing issue. Thank you for your patience.

Shahroz16 commented 1 year ago

Closing due to inactivity, please feel free to re-open in case the issue persists.