evollu / react-native-fcm

react native module for firebase cloud messaging and local notification
MIT License
1.73k stars 682 forks source link

Android issue. App doesn't receive notification in unloaded(killed) state #571

Open stsiushkevich opened 7 years ago

stsiushkevich commented 7 years ago

RN: 0.42.0 react-native-fcm: 7.4.0 Android

When the application is in the unloaded state my event handler doesn't trigger.

This is my code:

  addPushNotificationReceivedEventListener (handler) {
    const isIOS = this.isIOS()
    if (handler) {
      return FCM.on(FCMEvent.Notification, n => {
        setTimeout(() => { handler(n) }, 500)

        if (isIOS) {
          switch (n._notificationType) {
            case NotificationType.Remote:
              n.finish(RemoteNotificationResult.NewData)
              break
            case NotificationType.Local:
              n.finish()
              break
            case NotificationType.NotificationResponse:
              n.finish()
              break
            case NotificationType.WillPresent:
              n.finish(WillPresentNotificationResult.All)
              break
          }
        }
      })
    }
    return null
  }
stsiushkevich commented 7 years ago

related issue https://github.com/evollu/react-native-fcm/issues/341

@Override
public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    this.setIntent(intent);
}

This code doesn't solve the problem

stsiushkevich commented 7 years ago

I have found https://github.com/evollu/react-native-fcm/issues/504 and https://github.com/evollu/react-native-fcm/issues/531 issues but these approaches don't work.

evollu commented 7 years ago

unloaded state I assume when app is killed? did you run your listener outside of component lifecycle?

stsiushkevich commented 7 years ago

Ok. But Android receives notification in the system tray without triggering my handler with an incorrect icon. How can I set it?

evollu commented 7 years ago

I assume incorrect icon means a white icon? You need to make a white only icon for notification for Lollipop+, check readme

You need to run your listener outside of component lifecycle to have the callback triggered when app is not running.

stsiushkevich commented 7 years ago

OOO thank you! I'm going to try it right now!

stsiushkevich commented 7 years ago

Unfortunately, I cannot get such behavior when my handler trigger when the app is in the killed state.


// PushNotificationUtils.js
export default class PushNotificationUtils {
  static sendLocalNotification (data) {
    FCM.presentLocalNotification({...data,
      ...{
        sound: 'default',
        click_action: 'ACTION',
        priority: 'high',
        auto_cancel: true,
        large_icon: 'ic_launcher',
        icon: 'info',
        vibrate: 300,
        show_in_foreground: true
      }
    })
  }

  static addPushNotificationReceivedEventListener (handler) {
    if (handler) {
      return FCM.on(FCMEvent.Notification, n => {
        setTimeout(() => { handler(n) }, 500)

        if (isIOS()) {
          switch (n._notificationType) {
            case NotificationType.Remote:
              n.finish(RemoteNotificationResult.NewData)
              break
            case NotificationType.Local:
              n.finish()
              break
            case NotificationType.NotificationResponse:
              n.finish()
              break
            case NotificationType.WillPresent:
              n.finish(WillPresentNotificationResult.All)
              break
          }
        }
      })
    }
    return null
  }
}

//myapp.js
PushNotificationUtils.addPushNotificationReceivedEventListener((n) => {
  if (isValidNotification(n)) {
    if (+n.id === 3) {
      VersionCheck.needUpdate()
        .then(res => {
          if (res.isNeeded) Linking.openURL(VersionCheck.getStoreUrl())
        })
    } else {
      appAuthToken.getSessionToken().then(token => {
        let { userId } = token.sessionToken.data
        if (userId === +n.userId) {
          const isFromTray = n.opened_from_tray
          const custom = PushNotificationParseUtils.getCustomData(n)
          if (isFromTray) {
            PushNotificationStore.pushNotification(custom)

            if (isIOS() && isAppActive()) {
              Actions.ConfirmAuthorizationPopup({ modalSceneName: CONFIRM_AUTHORIZATION, isVisible: true })
            }
          }

          const isLocal = n.local_notification
          if (!(isLocal || isFromTray)) {
            let {title, body} = PushNotificationParseUtils.getMainData(n)
            PushNotificationUtils.sendLocalNotification({...{title, body, big_text: body}, ...custom})
          }
        }
      })
    }
  }
})

export default function native (platform) {
  class MyApp extends Component {
    render () {
      const store = configureStore(getInitialState())

      store.dispatch(setPlatform(platform))
      store.dispatch(setVersion(VERSION, versionHead))
      store.dispatch(setManufacturer(DeviceInfo.getManufacturer()))
      store.dispatch(setSystemVersion(DeviceInfo.getSystemVersion()))
      store.dispatch(setDeviceId(DeviceInfo.getDeviceId()))

      return (
        <Provider store={store}>
          <RouterWithRedux
            scenes={scenes}
            sceneStyle={styles.scene}
            backAndroidHandler={() => {
                   //a code
            }} />
        </Provider>
      )
    }
  }
  AppRegistry.registerComponent('myapp', () => MyApp)
}

It doesn't still trigger when the app is killed - it only works in background and foreground app state :(. Maybe is this impossible? Or I have old version of library?

About icon. Yes - it is white. I can set it with tag in for default icon. You set large icon with notification.setLargeIcon(largeIconBitmap); in javaFIRLocalMessagingHelper class. Can I use similar api in my manifest file? For example: <meta-data android:name="com.google.firebase.messaging.large_icon" android:resource="@mipmap/ic_launcher" />? Does such ability exist?

evollu commented 7 years ago

ah yes. need react-native-fcm 8+ I think

for large_icon. I'm not sure. perhaps not because FCM SDK doesn't support large icon. You can check if android itself has a way to set default large icon. otherwise you need to use custom_notification, then you can pass large_icon property

stsiushkevich commented 7 years ago

Ok.. thank you! I think setting large_icon property in my version of library won't set my custom icon because in the killed state of app code of your library won't trigger. Furthermore, I think react-native-fcm v8.0.0 will work exactly same as my version in the case when the app is killed because I didn't find any significant changes in v8.0.0 android source code. I cannot upgrade my project to react-native 0.47.0+ because many of my libraries will crash((

evollu commented 7 years ago

feel free to upgrade to latest if your rn is > 0.40, the latest code fixed compatibility issue

shekharskamble commented 6 years ago

@stsiushkevich is your issue resolved? facing same problem... cant get FCM.on if app is killed...