-
Notifications
You must be signed in to change notification settings - Fork 34
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
Design configurable notification schedules #900
Comments
Ideally, with local notifications, we would be able to create notifications according to schedule in JavaScript. However, we don't know that this will always work when the app is in the background. |
Given that a mechanism already exists for creating reminder push notifications, I am leaning towards saying we should just expand on it. The challenge that this approach faces is that the user's preference for 'time of day' must be somehow recorded on the server, so that the push notification logic respects the user's chosen time. |
Couple of high level comments on this:
|
To me the bigger questions are:
|
I think we had previously said that if notifications were local, the group assignments could be part of the OPCodes, sorted out beforehand. But with server-side notifications, we wouldn't have to worry about this and it'd be less complex.
Agreed. If possible, it'd be nice to maintain only one notification mechanism
I did plan on having an action button that would shortcut to the profile for the 'time of day' to be changed. I don't think the action button is strictly necessary though - the 'time of day' setting could still be accessed and updated in the profile tab. We just have to make sure that at some point, people are informed that the setting exists Thoughts? |
I guess we could also put it into the onboarding flow, but I am loath to increase the hoops that people have to jump through while installing the app.
On the other hand, local notifications are more reliable than remote notifications (remote notifications require a data network to be delivered and local notifications can be instantaneous). And once we switch to react native, the plugins are likely to be better maintained. So let's first start with what would be the ideal functionality and then go down the ease of implementation and maintainability route. It sounds like the ideal functionality is action buttons? what would we want to happen when the user clicks on the action button? Because the only thing that is broken right now is the ios callback when the user clicks on the local notification, and I think we can fudge that because we do receive it as a remote notification. |
So the ideal functionality, regardless of implementation, looks like this: Reminders come in according to schedule, considering both 1) the schedule assignment and 2) the user's time preference When a reminder shows, the primary interaction (clicking the notification) opens the label screen and marks that the session was started via a reminder so that we can track it later for analysis. For the post-migration future, once we are using React Native, I think that the action button will be much easier to implement, regardless of whether the scheduling happened on the server or the phone. |
When you say the callback is broken, do you mean it doesn't open the app? What happens instead on click? |
Ok, so then I think we should implement the action button, hacking it if necessary. Note that we can implement the action button in two ways:
so we still have some flexibility there
The app is launched, but the callback in After I push the point release out to staging, I'll file an issue and put in all the details. |
New considerations:
Pros for phone:
Pros for servers:
At least for now, it seems like phone is the clear winner, given the simplicity and the time constraints |
To store data on the server:
After writing this out though, I do think that the profile is better because:
|
From my three-day "pilot test" of e-mission/e-mission-phone#969 on a test phone, the scheduling is working as expected - reliably and punctual to the minute. There are one or two minor things I'd like to adjust before a release. I'll open a follow-up PR today or tomorrow. (1- on Android, see if I can get the time picker to automatically open when the "Change Time" redirect is handled. 2- make sure NotificationScheduler is initialized even if user doesn't open to the Profile tab, config-permitting) |
@JGreenlee couple of things:
|
@JGreenlee Also, let's think through and document what will happen to existing users when the app is updated.
|
@JGreenlee while testing this to see if the crash occurs with an old style config, I found that the module is apparently never initialized. I changed the code to:
And launched the final app (not em-dev-app) on android, where I can see console logs even before chrome was connected I do see messages for CONFIG_READY
But no I wonder if this is because we initialize the module after the intro is done |
Yup, this is only initialized in
So if the user does not go to the settings, we will not register for the ionicReady callback or the configReady callback and will not set up any notifications |
@shankari Yes, those are both things I want to address in the follow-up commit NotificationScheduler is currently initiated from the Profile screen, but the user might not necessarily open that after onboarding. So it should be initialized from the label screen, or directly after onboarding And secondly, it is initialized without regard to config options. It should only initialize when |
Regarding i18n, if the study will have users who prefer different languages, we can specify the text like this:
(just like we did for time-use) |
@JGreenlee Right, it won't crash since it is not a native code change, but it won't schedule any notifications.
Maybe we should switch to local notifications for all programs so that we can get the benefit of the flexible time of day.
Yeah I think we need to do this
Do you have an ETA for these follow-up changes? If you can't get to them, I can address them this weekend. |
I am working on this for now
|
Tomorrow, or maybe late tonight (depends on my sinuses) |
LMK if your sinuses don't cooperate and I can take over tomorrow
|
If the program/study has flexible notifications configured, we do not want to send push notifications from the server. These are inflexible, and will be generated every day at the same times, so we will not actually see flexibility in the notifications. So we check the config and skip the server side notification if flexible notifications are configured. This is an implementation of e-mission/e-mission-docs#900 (comment) Testing done: Without flexible notifications ``` $ ./e-mission-py.bash bin/push/push_remind.py /Users/kshankar/e-mission/gis_branch_tests/bin/push/push_remind.py:20: SyntaxWarning: "is not" with a literal. Did you mean "!="? if r.status_code is not 200: storage not configured, falling back to sample, default configuration URL not formatted, defaulting to "Stage_database" Connecting to database URL localhost DEBUG:root:STUDY_CONFIG is stage-program DEBUG:root:About to download config from https://raw.githubusercontent.com/e-mission/nrel-openpath-deploy-configs/main/configs/stage-study.nrel-op.json DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): raw.githubusercontent.com:443 DEBUG:urllib3.connectionpool:https://raw.githubusercontent.com:443 "GET /e-mission/nrel-openpath-deploy-configs/main/configs/stage-study.nrel-op.json HTTP/1.1" 200 1697 DEBUG:root:Successfully downloaded config with version 1 for Staging environment for testing studies only and data collection URL https://openpath-stage.nrel.gov/api/ DEBUG:root:Getting tokens matching query {'user_id': {'$in': [UUID('53b18320-898d-4c2b-abad-1e9eabe0385e'), UUID('1aa2c106-70f5-4525-b170-5b367adb6323'), UUID('6afb9865-c48b-4d35-a64c-c94f5a9da5cb')]}} WARNING:root:ignoring entry {'curr_platform': 'ios'} due to None values WARNING:root:ignoring entry {} due to None values WARNING:root:ignoring entry {'curr_platform': 'ios'} due to None values DEBUG:root:user_id_list of length 3 -> token list of length 0 DEBUG:root:module_name = emission.net.ext_service.push.notify_interface_impl.firebase DEBUG:root:module = <module 'emission.net.ext_service.push.notify_interface_impl.firebase' from '/Users/kshankar/e-mission/gis_branch_tests/emission/net/ext_service/push/notify_interface_impl/firebase.py'> DEBUG:root:interface_obj_fn = <function get_interface at 0x11271b310> DEBUG:root:interface_obj = <emission.net.ext_service.push.notify_interface_impl.firebase.FirebasePush object at 0x112767790> DEBUG:root:interface_obj = <emission.net.ext_service.push.notify_interface_impl.firebase.FirebasePush object at 0x112767790> DEBUG:root:len(token_list) == 0, skipping fcm token mapping to save API call after mapping iOS tokens, imported 0 -> processed 0 combo token map has 0 ios entries and 0 android entries DEBUG:urllib3.util.retry:Converted retries value: 3 -> Retry(total=3, connect=None, read=None, redirect=None, status=None) DEBUG:root:{'ios': {'multicast_ids': [], 'success': 0, 'failure': 0, 'canonical_ids': 0, 'results': [], 'topic_message_id': None}, 'android': {'multicast_ids': [], 'success': 0, 'failure': 0, 'canonical_ids': 0, 'results': [], 'topic_message_id': None}} ``` With flexible notifications ``` $ STUDY_CONFIG=denver-casr ./e-mission-py.bash bin/push/push_remind.py /Users/kshankar/e-mission/gis_branch_tests/bin/push/push_remind.py:20: SyntaxWarning: "is not" with a literal. Did you mean "!="? if r.status_code is not 200: storage not configured, falling back to sample, default configuration URL not formatted, defaulting to "Stage_database" Connecting to database URL localhost DEBUG:root:STUDY_CONFIG is denver-casr DEBUG:root:About to download config from https://raw.githubusercontent.com/e-mission/nrel-openpath-deploy-configs/main/configs/denver-casr.nrel-op.json DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): raw.githubusercontent.com:443 DEBUG:urllib3.connectionpool:https://raw.githubusercontent.com:443 "GET /e-mission/nrel-openpath-deploy-configs/main/configs/denver-casr.nrel-op.json HTTP/1.1" 200 2221 DEBUG:root:Successfully downloaded config with version 1 for Denver E-bike Rebate Program Data Collection and data collection URL https://denver-casr-openpath.nrel.gov/api/ DEBUG:root:Found flexible notification configuration, skipping server-side push ```
The 'pilot test' schedule was not that sophisticated: "schedule": [
{
"start": 0,
"end": 1,
"intervalInDays": 1
},
{
"start": 3,
"intervalInDays": 2
}
], I just wanted to make sure notifications came on the correct days:
I also varied the On Thursday I set it up on a real phone, I observed that notifications came on Thursday and Friday but not Saturday.
The full "reminderSchemes": {
"weekly": {
"title": "{Please take a moment to label your trips}",
"text": "{Click here to open the app and view unlabeled trips}",
"schedule": [
{
"start": 0,
"end": 1,
"intervalInDays": 1
},
{
"start": 3,
"intervalInDays": 2
}
],
"defaultTime": "21:00"
},
"week-quarterly": {
"title": "{Please take a moment to label your trips}",
"text": "{Click here to open the app and view unlabeled trips}",
"schedule": [
{
"start": 0,
"end": 1,
"intervalInDays": 1
},
{
"start": 3,
"intervalInDays": 2
}
],
"defaultTime": "22:00"
},
"passive": {
"title": "{Please take a moment to label your trips}",
"text": "{Click here to open the app and view unlabeled trips}",
"schedule": [
{
"start": 0,
"end": 1,
"intervalInDays": 1
},
{
"start": 3,
"intervalInDays": 2
}
],
"defaultTime": "23:00"
}
} |
Follow-up PR: e-mission/e-mission-phone#976
I didn't get this working, but I think it's ok. The redirect works and the Profile Tab opens - it just would have been nice for the time picker to automatically pop up |
Yeah I would not worry too much about it now; can handle in a later PR or after the rewrite.
For testing, I propose the following single scheme for all the schemes
So if the Denver folks install tomorrow, they should see:
We can change the config on Monday and then they can send out emails to participants at the end of the month (Wed). |
The one other fit and finish change we may want to do for this (can wait until the next point release) is to show users which group they are in. Unless we are worried that it will bias the results somehow to do that. Filed #913 to track this |
We have now largely deployed this. Let us close this giant issue and track improvements/fit-finish issues separately for clarity. I am aware of at least two:
Not sure if @JGreenlee is still going to try to have the time picker automatically pop up. |
We want to allow for a more flexible notification system that can be tailored to any of multiple "schemes" and also consider the user's preference for the timing of the notification.
The interval of the notifications (i.e. daily? weekly?), will be determined by the user's assignment to one of many groups.
The time of day at which the notification comes (i.e. noon? 8pm?) will be specified by the user.
The open question is whether the logic for scheduling notifications should be handled server-side or client-side.
The current system uses push notifications to send a reminder at the same time every day. Thus, the notification is created server-side and pushed out.
Server-side / push notification pros:
Client-side / local notification pros:
The text was updated successfully, but these errors were encountered: