Code inside notification on click does'nt execute when app is killed in ios.
See original GitHub issueHello, i want to execute some code inside notification.on(‘click’) this works well when the app is in front on in the background but does’nt when the app is killed on ios. This does work on android even if the app is killed but it does’nt on ios.
Your Environment
- Plugin version: ^0.9.0-beta.3
- Platform: IOS
- OS version: 12.1
- Device manufacturer / model: IPHONE 6
- Cordova version (
cordova -v
): 8.1.2 - Cordova platform version (
cordova platform ls
):4.5.5 - Plugin config
- Ionic Version (if using Ionic) ionic 4
Expected Behavior
When clicking on the notification we should get redirected to the specified page.
Actual Behavior
When clicking on the notification the app starts and opens the home page. It does’nt redirect.
Steps to Reproduce
In my app.component.ts :
initializeApp() {
this.platform.ready().then(() => {
this.localNotifications.on('click').subscribe((data) => {
this.router.navigateByUrl('/notification/' + data.id);
});
});
This works well in android in the three different states of the app, but does’nt on IOS when the app is killed.
Context
Im trying to execute the code inside the click event, it does work when the app is opened or in the background but not when the app is killed.
Debug logs
Include iOS / Android logs
- ios XCode logs
- Android: $ adb logcat
Issue Analytics
- State:
- Created 4 years ago
- Comments:7
Top Results From Across the Web
ios - Notification - when app is killed - Stack Overflow
This is a normal behavior, and there is no workaround. If your app is killed by the user, it won't be able to...
Read more >onNotification not being called when app was killed on iOS
It gets called when the app starts in background due to geofencing events and a local notification is shown. During this app start...
Read more >App does not launch by data FCM | Apple Developer Forums
Hi all,. We used to launch our app in background by a silent FCM push and the app will display a local notification...
Read more >Notifications Not Shown - Mobile Push
When an app is in a Force Stopped / Force Killed state most events including FCM messages for push notifications will not be...
Read more >How to run code when your app is terminated
When you check that box and click Run, you've modified the Run schema so that your app is always run as a background...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
EDIT 2 Another thing I stumbled into: For me I had to schedule notifications for 3 days (~180 pushs). Did not work. There is a limit of 64 local notifications which can be scheduled.
So I ended up having 2 queues. The ones which are to be fired and the ones which should be fired. And then always updating onResume and on user interaction when the user canceled some out.
@guntherhoppe @pandeeswaran @adamalexander @kasback @petenickless @maniveltvl
There are different things one needs to consider if using a framework like Angular and Ionic.
First app start: What happens?
Usual setup
Our app starts, native code gets executed
Native local push plugin code gets executed and stores (queues) native information for later when our HTML5 world is available
Parallel a WebView gets instantiated and loads the index.html, which then loads everything we need for our HTML5 app. 3.1 Async loading all JS plugin files (the bridge between our HTML5 and the native world). 3.2 Async loading our angular / ionic application file/s.
The local-notification.js file loaded first. 4.1 local-notification.js attaches and listens for the
deviceready
event. 4.2 All plugins loaded and thedeviceready
event fires. 4.3 By default the following code fireQueuedEvents gets executed on thedeviceready
event. 4.4* Now all queued events from our local push plugin fire: None at this point (first app start, remember?).*We jump later back here
await this.platform.ready();
5.4 Now the plugins are there for sure.Setup the event listeners
.Run code in the right context
Angular uses zoneJS for change detection. Sometimes something is triggered in pure JS and your code gets executed (you would see an alert message or a console.log), but the change detection of angular does not get triggered and anything you would write in there to get updated in the angular / ionic world, would not take effect. Therefore we use
NgZone
and run our code to be executed in the angular zone and change detection will work - also the routing.Any events? Nope. Let’s create and schedule some (2x: one push in 10 and another one in 30 seconds)! 6.1 App runs in background, bootstrapped and listening for our events. 6.2 Push comes - we do tap the push - the click event fires, our subscribe block gets executed in the angular context, change detection runs and voila, we did route to the notification detail page.
Let’s force quit / close the app and wait for the 2nd push to arrive and tap it.
We start again at the top at point 1 and go up to point 4.4. This time we do start the app the 2nd time and we do have one queued event! Wooohoo! Proceed as before and fire and forget all the queued events!
Does it now work as before when the app was in front- or background? No
Did we already had setup our listeners in Angular / Ionic before the push plugin fired the event? No - We did not setup event listener before the events fired from local-notification.js.
Will the click subscription not just fire after we subscribed because there was some data and someone should have stored it? No - It makes no sense firing events just when someone did subscribe. Just because you subscribed multiple times, does not mean you clicked multiple times.
Is there some data now? No - We were too late. The push click event did fire just a moment before.
Can we fix this? Yes
Can we skip initial firing the events of the local push plugin and postpone the events until we know that we have setup everything in our application (HTML5 world)? Yes - As you’ve maybe seen the skipLocalNotificationReady is being checked before firing the events. Set the global
skipLocalNotificationReady
variable totrue
before the local push plugin is loaded.Working setup
index.html:
Can we now manually trigger the queued events of the local push plugin? Yes - Modify our PushService to fire the queued events with calling the
fireQueuedEvents()
method:Hope this helps someone.
EDIT: Additional notes
The above ONLY applies to the “CLICK” event (
cordova.plugins.notification.local.on('click',..)
. I have setup alert messages for the click and trigger event. The click always came after a tap on the Notification (App foreground, App background and App was closed (did force quit the app)). Thetrigger
event however did ONLY appeared when the app was in foreground. It did NOT fire the trigger event, when my app was in background and I then opened the app (via click or just opened the app by tapping the app icon).Can we work around this? Yes
How? Save a list of all push alerts you want to trigger with their time locally on the device (persistently, not local storage). Update the list also, if you need to and times change etc.
Then on app start and on resume, compare the device time with the time of all notifications.
Attention: The timeout is needed, in case some native plugins will be called (for example reading the persistent data) or there will be some problems.
Source: Cordova 9 iOS resume event
Get triggered notifications could be something like that (I used linqTS
I determined this problem also on Android platform. My analysis point to a simple fact: The LocalNotification#fireEvent is performed before a listener could even be registered at app startup. I also registered my listener within app.component.ts, but unfortunately this is simply too late in real application scenarios. It’s a timing issue.
The “deviceready” event of the (native) plugin is called before the actual “deviceready” is performed on Typescript side (not Javascript side!). So there is actually no chance to handle the click event on app cold start with things like Ionic’s ```Platform.ready()`` within your app components at all.
I implemented a (really 😉 ) “hacky” workaround, which does the trick by intercepting the click event: (workaround goes directly into index.html)
With that you are able to retrieve an once occurred local notification afterwards when you app code actually is up an running by checking: