Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Couldn't make it work when app is killed [android] #3

Open
SushilShrestha opened this issue May 29, 2016 · 43 comments
Open

Couldn't make it work when app is killed [android] #3

SushilShrestha opened this issue May 29, 2016 · 43 comments

Comments

@SushilShrestha
Copy link

I am working on push notification for my app. I followed instructions from documentation. The app notifies me when app is on background but not when app is killed. Am I missing something?

import GCM from 'react-native-gcm-push-notification'
import Notification from 'react-native-system-notification'

var notification = GCM.popInitialNotification()
if (notification) {
  var info = JSON.parse(notification.info)
  Notification.create({
    subject: info.subject,
    message: info.message
  })
  GCM.stopService()
} else {
  class App extends Component {
    componentDidMount () {
      GCM.addEventListener('register', function (data) {
        if (!data.error) {
          console.log('send gcm token to server', data.registrationToken)
        }
      })
      GCM.addEventListener('notification', function (notification){
        console.log('receive gcm notification', notification)
        var info = JSON.parse(notification.data.info)
        if (!GCM.isInForeground) {
          Notification.create({
            subject: info.subject,
            message: info.message
          })
        }
      })

      GCM.requestPermissions()
    }
    render () {
      return <App />
    }
  }

  AppRegistry.registerComponent('App', () => App)
}
@evollu
Copy link
Owner

evollu commented Jun 4, 2016

sorry to take it so long to respond. I was working on fcm project.
are you passing notification payload or data payload? If you are passing data payload, gcm will not wake up when app is killed

@ghost
Copy link

ghost commented Jun 6, 2016

This is probably the same issue I pointed out in commit comment. popInitialNotification just never returns a notification in Android, It would be nice to find the cause and fix it.

@evollu
Copy link
Owner

evollu commented Jun 6, 2016

change new GcmPackge() to new GcmPackage(getIntent() in MainActivity.java
this should fix it

@ghost
Copy link

ghost commented Jun 6, 2016

Will try. It would be great if this helped.

@ghost
Copy link

ghost commented Jun 6, 2016

App shows error when I supply getIntent() into new GcmPackage(). Menu stops working and after a while, app crashes.
screenshot_2016-06-06-19-07-14

@ghost
Copy link

ghost commented Jun 6, 2016

It starts fine without getIntent().

@evollu
Copy link
Owner

evollu commented Jun 6, 2016

Sorry I don't have any project using this plugin now. Can you debug into getConstants function in GcmModule.java file?

@ghost
Copy link

ghost commented Jun 7, 2016

I don't have clue how. I am not developing in Java, I am just doing PN project in WebStorm.

But here is report from fabric:

Fatal Exception: java.lang.RuntimeException: Failed to initialize bridge
       at com.facebook.react.bridge.CatalystInstanceImpl.<init>(CatalystInstanceImpl.java:103)
       at com.facebook.react.bridge.CatalystInstanceImpl.<init>(CatalystInstanceImpl.java:39)
       at com.facebook.react.bridge.CatalystInstanceImpl$Builder.build(CatalystInstanceImpl.java:551)
       at com.facebook.react.ReactInstanceManagerImpl.createReactContext(ReactInstanceManagerImpl.java:867)
       at com.facebook.react.ReactInstanceManagerImpl.access$700(ReactInstanceManagerImpl.java:102)
       at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:198)
       at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:181)
       at android.os.AsyncTask$2.call(AsyncTask.java:287)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:838)
Caused by java.util.concurrent.ExecutionException: java.lang.NullPointerException
       at com.facebook.react.common.futures.SimpleSettableFuture.get(SimpleSettableFuture.java:68)
       at com.facebook.react.bridge.CatalystInstanceImpl.<init>(CatalystInstanceImpl.java:90)
       at com.facebook.react.bridge.CatalystInstanceImpl.<init>(CatalystInstanceImpl.java:39)
       at com.facebook.react.bridge.CatalystInstanceImpl$Builder.build(CatalystInstanceImpl.java:551)
       at com.facebook.react.ReactInstanceManagerImpl.createReactContext(ReactInstanceManagerImpl.java:867)
       at com.facebook.react.ReactInstanceManagerImpl.access$700(ReactInstanceManagerImpl.java:102)
       at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:198)
       at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:181)
       at android.os.AsyncTask$2.call(AsyncTask.java:287)
       at java.util.concurrent.FutureTask.run(FutureTask.java:234)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
       at java.lang.Thread.run(Thread.java:838)
Caused by java.lang.NullPointerException
       at com.oney.gcm.GcmModule.convertJSON(GcmModule.java:118)
       at com.oney.gcm.GcmModule.getConstants(GcmModule.java:76)
       at com.facebook.react.bridge.BaseJavaModule.writeConstantsField(BaseJavaModule.java:441)
       at com.facebook.react.bridge.NativeModuleRegistry.writeModuleDescriptions(NativeModuleRegistry.java:82)
       at com.facebook.react.bridge.CatalystInstanceImpl.buildModulesConfigJSONProperty(CatalystInstanceImpl.java:368)
       at com.facebook.react.bridge.CatalystInstanceImpl.initializeBridge(CatalystInstanceImpl.java:127)
       at com.facebook.react.bridge.CatalystInstanceImpl.access$200(CatalystInstanceImpl.java:39)
       at com.facebook.react.bridge.CatalystInstanceImpl$1.call(CatalystInstanceImpl.java:96)
       at com.facebook.react.bridge.CatalystInstanceImpl$1.call(CatalystInstanceImpl.java:91)
       at com.facebook.react.bridge.queue.MessageQueueThreadImpl$1.run(MessageQueueThreadImpl.java:73)
       at android.os.Handler.handleCallback(Handler.java:725)
       at android.os.Handler.dispatchMessage(Handler.java:92)
       at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
       at android.os.Looper.loop(Looper.java:153)
       at com.facebook.react.bridge.queue.MessageQueueThreadImpl$3.run(MessageQueueThreadImpl.java:187)
       at java.lang.Thread.run(Thread.java:838)

@evollu
Copy link
Owner

evollu commented Jun 7, 2016

at com.oney.gcm.GcmModule.convertJSON(GcmModule.java:118)

so here is the issue. seems like something null is passed into the function

@evollu
Copy link
Owner

evollu commented Jun 7, 2016

try this:
in GcmModule.java file
change Bundle bundle = mIntent.getBundleExtra("bundle"); in line 75 to
Bundle bundle = mIntent.getExtras();

@evollu
Copy link
Owner

evollu commented Jun 7, 2016

I use Android Studio to debug native code and it is convenient and has better logging

@ghost
Copy link

ghost commented Jun 7, 2016

Yeah, that much I could conclude as well (I mean, the null). ;-)

This happens at the normal start of the app. IIRC you have added the JSON parsing into Java part and it wasn't there before. I think the problem is that with plain start of the app, there is no initial notification (and therefore, null). Maybe it should be ifed properly to distiguish between normal start and start driven by offline notification arriving.

Working on something else, but will see at it later.

@evollu
Copy link
Owner

evollu commented Jun 7, 2016

good catch!
you can use mIntent.getAction().equals("android.intent.action.MAIN") to check if it is normal start up

@evollu
Copy link
Owner

evollu commented Jun 7, 2016

another solution is checking if mIntent.getBundleExtra("bundle") is null. I think this makes more sense here. Can you verify if "click_action" is passed into the bundle when you receive notification?

@ghost
Copy link

ghost commented Jun 8, 2016

I changed the appropriate part to:

        if (mIntent != null) {
            Bundle bundle = mIntent.getBundleExtra("bundle");
            if (bundle != null) {
                String bundleString = convertJSON(bundle);
                Log.d(TAG, "bundleString: " + bundleString);
                constants.put("initialNotification", bundleString);
            }
        }

but the problem is that I cannot get any events in the app itself. Because of this in GcmModule constructor:

        if (mIntent == null) {
            listenGcmRegistration();
            listenGcmReceiveNotification();
            getReactApplicationContext().addLifecycleEventListener(this);
        }

I presume it all needs a bit of redesign,

@ghost
Copy link

ghost commented Jun 8, 2016

That is, I think every mIntent check should discriminate not between null / non-null case but between "non-null and started because of offline notification" / "other". It is probably possible as I presume intent is different (and hopefully known) for the case of offline notification, and all the rest should be treated as standard startup.

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

you don't get any events because mIntent.getBundleExtra("bundle") is always null.
Here is working code for my fcm project. firebase cloud messaging is mento replace GCM. any reason you can't upgrade to newer google play service?

Map<String, Object> constants = new HashMap<>();
        if (mIntent != null) {
            if(mIntent.getExtras() != null) {
                Map<String, Object> extra = new HashMap<>();
                Bundle data = mIntent.getExtras();
                Set<String> keysIterator = data.keySet();
                for(String key: keysIterator){
                    extra.put(key, data.get(key));
                }
                constants.put("initialData", extra);
            }
            constants.put("initialAction", mIntent.getAction());
        }
        return constants;

@ghost
Copy link

ghost commented Jun 9, 2016

I'm not getting any action because listenGcmRegistration(); was not called because I pass non-null mIntent. That thing needs redesign, isn't it? Now you either give me initialNotification but not giving me registration and subsequent ones, or the other way - I don't get initial one but get all the others.

@ghost
Copy link

ghost commented Jun 9, 2016

Are you sure that your above code is able to get both inital notification, device id registration and subsequent push notification while app is live? Because that's what is not working - getting both. Now the if (mIntent == null) I posted above rules one of it out.

@ghost
Copy link

ghost commented Jun 9, 2016

Unless I do not understand something and getIntent() returns null in normal appo startup, but it does not seem to be the case.

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

if you start app normally, getIntent() with return an Intent with getAction() == "android.xxxx.DEFAULT". It will never be null

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

the code above is just for inital notification. It is RN's getContants method. device id registration and subsequent push notification while app is live is handled correctly by this library.

@ghost
Copy link

ghost commented Jun 9, 2016

But again, if I pass getIntent() (which is not null), the registrations is not working. Because of if in the constructor.
Shouldn't both be working at the same time?

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

oh man, the code needs so much refactoring... Are you sure you can't upgrade to firebase cloud messaging?

@ghost
Copy link

ghost commented Jun 9, 2016

(that is, not at the same time, but, pls:

  • if I pass getIntent(), the registration and notification receiving is not started;
  • if I start app normally, that means it won't get registration nor notifications,
  • I would like app, when normally started, to receive registrations and notifications
  • so, could it be made, somehow, that even I getIntent() is passed, the registration and notification is still received?)

FCM is part of firebase3, which is not working with RN.

@ghost
Copy link

ghost commented Jun 9, 2016

What I was suggesting, mIntent test should not check for null, but somehow otherwise to distiguish "started because offline notification" versus "started normally / null passed".

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

fcm is working for RN. It is GCM with another name. Check https://github.com/evollu/react-native-fcm.
I'm keeping the null check in case someone doesn't need initial notification and initiates the package without getIntent().

@ghost
Copy link

ghost commented Jun 9, 2016

That's what I was suggesting, keep the null check but you need add smarter check to it:

Discriminate between two cases:

  1. null or normal start w/ getIntent() (listen to reg and notif)
  2. getIntent w/ offline notification (do not listen)

Now it discriminates between:

  1. null (listen to reg and notif)
  2. normal start w/ getIntent() or getIntent w/ offline notification (do not listen)

The "normal start w/ getIntent()" ending up with "do not listen" is incorrect.

Libin Lu wrote:

fcm is working for RN. It is GCM with another name. Check
https://github.com/evollu/react-native-fcm.
I'm keeping the null check in case someone doesn't need initial
notification and initiates the package without getIntent().


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#3 (comment),
or mute the thread
<https://github.com/notifications/unsub
scribe/AANjsVhYOkc224CvhfCjQrmz5Gui8qxaks5qKC5kgaJpZM4IpUDR>.

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

agreed. let me work on it later today or tomorrow and try to fix the code

@ghost
Copy link

ghost commented Jun 9, 2016

BTW thanks for pointing to fcm working in RN, I had the impression it is part of firebase3, which is not RN compatible yet.

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

if you decide to use FCM, I will drop support for this library. It is just an headache to maintain an outdated library and code not written by me

@ghost
Copy link

ghost commented Jun 9, 2016

Will look if it is usable tomorrow.

@evollu
Copy link
Owner

evollu commented Jun 9, 2016

cool. I will wait for your updates then

@aymericbouzy
Copy link

Hi, I'm running into the same problem. From what I see in FCM repository, there seems to be a lot of issues to solve still. Is there a partial fix at least for the time being?

@evollu
Copy link
Owner

evollu commented Jul 6, 2016

issues in FCM is mostly configuration issue and use questions
have you tried it?

@aymericbouzy
Copy link

not yet. I am going to, I'll keep you posted

@aymericbouzy
Copy link

From the documentation, it sounds like FCM does not support notifications sent when app is killed : is that really the case? If so, there's no point for me to switch just yet.

@evollu
Copy link
Owner

evollu commented Jul 6, 2016

it should support as FCM runs on the same framework as GCM
can you share the reference that it doesn't support?

@aymericbouzy
Copy link

I meant from the react-native-fcm repo :
https://github.com/evollu/react-native-fcm#i-cant-get-notification-when-app-is-killed

@evollu
Copy link
Owner

evollu commented Jul 6, 2016

oh, if you want to show banner when app is killed/ in background, you should always use notification payload instead of data payload. It is exact same behavior as GCM.

@aymericbouzy
Copy link

Ok thanks, I will try this. May I suggest you to create a gitter chat room for this repository ? I'm sure it would make things easier for this type of conversation.

@evollu
Copy link
Owner

evollu commented Jul 6, 2016

gitter chat created for fcm repo

@aymericbouzy
Copy link

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants