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

notification went off at wrong time? #1212

Closed
kerryf88 opened this issue Feb 11, 2017 · 24 comments
Closed

notification went off at wrong time? #1212

kerryf88 opened this issue Feb 11, 2017 · 24 comments

Comments

@kerryf88
Copy link

kerryf88 commented Feb 11, 2017

Your Environment
Plugin version: 0.8.4
Platform: iOS 9.3.4
OS version: Mac 10.11
Device manufacturer / model: iPad Air
Cordova version (cordova -v): 6.4.0
Cordova platform version (cordova platform ls): iOS 3.9.2

Expected Behavior
Notification daily at 8am and 8pm

Tell us what should happen
Gives off notification at 8am and 8pm everyday.

Actual Behavior
Wrong notification time

Tell us what happens instead
Give off notification at correct time but once I open the notification, the next day's notification time will be wrong/different.

Steps to Reproduce
Reproduce this issue; include code to reproduce, if relevant

`<script type="text/javascript">
document.addEventListener("deviceready",onDeviceReady,false);

function onDeviceReady() {
var _Daily_8_00_am = new Date("February 9, 2017 08:00:00");
var _Daily_8_00_pm = new Date("February 9, 2017 20:00:00");
cordova.plugins.notification.local.schedule([{
id: 1,
title: "Alert 1",
text: "This is alert 1 at 8am",
sound: "file://sounds/amazing_ringtone.mp3",
firstAt: _Daily_8_00_am,
every: "day"
},{
id: 2,
title: "Alert 2",
text: "This is alert 2 at 8pm",
sound: "file://sounds/amazing_ringtone.mp3",
firstAt: _Daily_8_00_pm,
every: "day"
}]);
}`

@rwillett
Copy link
Collaborator

  1. Fill the template in Ticket Template: If you ignore this template, we'll ignore your issue #1188 as it gives us more information.

  2. Useful information would be what plugin version.

  3. There are issues with the every: and at: combination. It is unlikely to ever work on IOS10 for example. You may be better off re-architecting your solution to pull every:

Rob

@kerryf88
Copy link
Author

Hi Rob
I've just updated my question.

I'm using IOS9 on the iPad, haven't updated to IOS10 because I'm worried plugins might not work.

So is there an alternative way for the plugin to work at notifying daily at 8am and 8pm if I can't use every: and at: combo?

@rwillett
Copy link
Collaborator

It should work but a lot of people have reported problems. We don't use every ourselves so can't say. Other people may be able to help.

If your application is being reopened each time, are you resetting things somehow. It might be worth checking what is actually scheduled.

@kerryf88
Copy link
Author

Hmm it could be, because if I don't open the app the notification seems to go off at the right time daily, but once I opened it the timing seems to go crazy. Maybe it has something to do with me putting the notification schedule functions under onDeviceReady()?

@rwillett
Copy link
Collaborator

The onDeviceReady is needed. Your plugin is not ready until the onDeviceReady event is set.

I suspect that you are rescheduling the notification, perhaps using the same id, when you are restarting the app.

I would write a piece of code that shows you the schedule each time you start or restart the app and see what it looks like.

@kerryf88
Copy link
Author

kerryf88 commented Feb 13, 2017

Just curious were the previously scheduled time being saved into the system even after I changed the notification time? Like if I had originally set the firstAt time for id 1:
var _Daily_8_00_am = new Date("February 9, 2017 08:00:00");

I install the app, and then I go ahead and change the firstAt notification time to:
var _Daily_8_00_am = new Date("February 10, 2017 17:00:00");

And I reinstall the app. Was the previously scheduled 8am notification being saved into the system until I use the "cordova.plugins.notification.local.cancel" function?

@kerryf88
Copy link
Author

I suspect that you are rescheduling the notification, perhaps using the same id, when you are restarting the app.

Yes I too suspect this, do you know if there is a way to stop the function from executing again when restarting the app? Because now the app works fine with the notifications IF I don't open it up, but once I opened one up, it tend to get all messed up with the future notifications. Sorry but I'm a beginner at coding, any advice will be appreciated!

@rwillett
Copy link
Collaborator

Its impossible to answer this question as we have seen no code.

As a suggestion you should check for what is scheduled and then only reschedule of you need to.

You have to learn how your app works I'm afraid :)

@kerryf88
Copy link
Author

kerryf88 commented Feb 14, 2017

I think I know what's the problem here. The app is re-executing the codes when I open it, so if I open after the scheduled time, for example the scheduled time is on 9th Feb at 8pm, and I open the app on the 9th of Feb at 9pm, the system recognise the date as a date in the past and thus sends a notification immediately. And the next day, the notification will start appearing at 9pm instead of 8pm.

I tried to overcome the prob by setting the time as below:

var today = new Date(); var tomorrow = new Date(); tomorrow.setDate(today.getDate()+1); tomorrow.setHours(20); tomorrow.setMinutes(0); tomorrow.setSeconds(0); var _Daily_8_00_pm = new Date(tomorrow);

this overcomes the problem of how the app recognising the date as a date in the past, but there is another issue with this one, as the code is executed everytime I open the app, if I open the app by accident past midnight (say at 10 Feb 1am), then the notification won't fire up until the next day (11 Feb). So frustrated!

@rwillett
Copy link
Collaborator

This is a simple coding issue. You are always executing the code on startup. You don't need to and probably shouldn't.

You need to start the code up and then check what has already been scheduled and then (and only then) work out what to schedule. There is an if statement needed somewhere in your code.

You cannot make ANY assumptions about when your code is started. You must check every single time the app starts up without exception and then work out what to do.

@kerryf88
Copy link
Author

kerryf88 commented Feb 14, 2017

ok this is what I come up with (based from my limited coding knowledge), but the app isn't working if I schedule the notification this way, so something must be wrong:

var _Daily_8_00_am = new Date("February 9, 2017 08:00:00");
var _Daily_8_00_pm = new Date("February 9, 2017 20:00:00");
cordova.plugins.notification.local.isScheduled(id, function(isScheduled){
if(isScheduled == true)
{
alert("already scheduled");
}
else
{
cordova.plugins.notification.local.schedule([{
id: 1,
title: "Alert 1",
text: "This is alert 1 at 8am",
sound: "file://sounds/amazing_ringtone.mp3",
firstAt: _Daily_8_00_am,
every: "day"
},{
id: 2,
title: "Alert 2",
text: "This is alert 2 at 8pm",
sound: "file://sounds/amazing_ringtone.mp3",
firstAt: _Daily_8_00_pm,
every: "day"
}]);
}
}

Am I on the right path?

@rwillett
Copy link
Collaborator

I think you are being too simplistic, you are simply checking for something (anything) being scheduled.

We check for everything that is being scheduled and work things out from there. You are better off (IMHO) checking everything and then working the lot out each time. We do this every time we start and every time the user comes out of background mode and it costs virtually nothing in terms of CPU and time. Don;t forget that when your app is in the background it could be suspended and so when you come out of background mode (3-5 days after you put it in?) things might be in a wholly different state.

See https://github.com/katzer/cordova-plugin-local-notifications/wiki/08.-Querying for more information.

You cannot assume anything about when the app starts or resumes, so assume the worst and plan for it.

@kerryf88
Copy link
Author

The way I set up my app is to completely terminate the app when user clicked "home" button, which means it doesn't runs in background at all. I think this is one of the reason why the codes were resetting each time I reopens the app as it's terminated/out of background mode when I close the app. I'll keep working on it and hope for the best, thanks.

@rwillett
Copy link
Collaborator

Why are you terminating the app rather than letting it go into background?

This is why your notifications are being called again and again. If you simply let the app suspend, this wouldn't happen when you resumed. It would still happen when you start and stop the app.

Normally there is no advantage to stopping and starting the app each time.

@kerryf88
Copy link
Author

Because I need the app to behave like this, i.e terminating the app immediately once the user clicked on the home button, as the suspending time of the app takes too long for the need of my app.

@kerryf88
Copy link
Author

Do you mean that if I untick the "UIApplicationExitsOnSuspend" or set the "Application does not run in background" to NO, then the notifications should work correctly?

@rwillett
Copy link
Collaborator

Because I need the app to behave like this, i.e terminating the app immediately once the user clicked on the home button, as the suspending time of the app takes too long for the need of my app.

Do you mean suspending the app or putting the app in the background? Putting the app in the background takes zero time, suspending the app takes from 0 mins to 15 mins. However, what is the issue or use case about it taking 0 to 15 mins?

No idea about UIApplicationExitsOnSuspend as we simply let the OS suspend the app when the user presses the home butto. Never needed to tick this.

@rwillett
Copy link
Collaborator

I think you need to look at your code and how you are doing notifications.

I also think that you need to understand what background processing your app is actually capable of. On IOS your app is only capable of running for a few minutes (0 - 15 mins, dependent on what the OS decides, not you) in the background. You cannot run JavaScript timers, you cannot run http sessions. There are ways around this but are beyond the scope of this thread. To all intents and purposes your app is suspended the moment you press the home button (or whatever).

When you resume your app, you will get an onResume event and your app will start off where you left it. This is how mobile apps work. All the apps I know about simply pause and resume as thats the way the OS is designed to work. Apps in the background do not consume anything and are free to resume at any time.

You have complicated the issue by starting and stopping the app for some reason you have not explained about, this may be the right thing to do for you, but until you say why you are doing this, I would be cautious. If users want to kill your app, simply let them swipe kill it.

Once you start to use the appropriate model, your notifications will become a little easier. However you may still need to check what notifications are scheduled, and work out what you need to reschedule.

Changing the behaviour of your app to either close or suspend to make local notifications work the way you want them to is the wrong approach. Change your code to work correctly.

Rob

@kerryf88
Copy link
Author

I have tried to run the app in background but because I have other codes within the onDeviceReady section that needs to be executed based on the current time. And if I run the app in the background and goes back to open the app at another time, the app is still stuck at from where I left it hours ago, which results in the other required functions from onDeviceReady not executed.

@Tawpie
Copy link

Tawpie commented Feb 15, 2017 via email

@kerryf88
Copy link
Author

kerryf88 commented Feb 15, 2017

The way I ask the app to terminate after the user clicked home button was made by selecting NO to "Application does not run in background". It seems the app never goes to a cold start when I reopens it even hours later, and always continues where I last left it.

Is onResume handler something for iOS or just android? As this sounds like this could work!

Also just out of curiosity, how many notifications can I schedule in total for iOS 9? Is there a limit?

@rwillett
Copy link
Collaborator

@Tawpie has described the situation very well indeed. We have both suggested much the same thing (though his explanation is clearer), you need to move your code into functions and work out what you need to execute.

You seem to have made something very complicated for something that could be very simple. Since you have still not explained your problem as to why you can't simple pause and resume, its difficult to know what to say.

I still think your coding design is wrong and you are forcing the OS to work the way you want it to to compensate for incorrect design.

onResume is for IOS and Android, I have no idea about Windows Phone.

There is a limit of 64 local notifications AFAIK.

@kerryf88
Copy link
Author

kerryf88 commented Feb 20, 2017

I still think your coding design is wrong and you are forcing the OS to work the way you want it to to compensate for incorrect design.

Hi guys, after some testings I've manage to get things working by letting the app run in background, I've also removed the "every" part and just setting up individual notification for now as I plan on updating my iOS to 10.

However I do have another question, at the moment each notification is only fired once at the scheduled time, is there a way for the notification to ring every minute (or for a customised time period) until the user opened the notification? The "every" function works to notify every minute but then it just keep sending the notification regardless of whether the user clicked on the notification or not. I don't suppose there is a snooze button available for the plugin so any ideas on what I can do to achieve that?

p.s not sure if I should start a new thread about this new question, but let me know if I should and I will do that.

@rwillett
Copy link
Collaborator

I'll close this and let you raise a new issue using the template.

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

No branches or pull requests

3 participants