Open Tawpie opened 6 years ago
ok. I got it figured out. There are two things happening:
To make it work, I am adding the action groups with a function that resolves a promise when the addAction plugin function completes. Scheduling uses this promise to actually do the scheduling.
I think there is a bug in the plugin somewhere, the fact that getNotificationCategoriesWithCompletionHandler
returns an empty set just before scheduling is "not right"
@Tawpie can you post some code on your 'solution'?
Here's my code for scheduling a single notification. I always use the array method of scheduling even for single notifications, it seems to work more reliably. We also use Hungarian notation for vars, I know, but it works for us. This means that vars that start with say, 'ks' for example, are "konstant, string" so we know it's a string that isn't supposed to change and was defined in our globals file.
The promise part happens in the getTestKatzerActionGroupArray()
method, I'll post that code in the next comment. What I'm doing is building a set of promises to 'add the action category' for each notification, then running them one after the other and when the last promise resolves I go ahead and cancel existing notifications and reschedule.
/**
* an_scheduleSingleLocalNotification
*
* queue up a system local notification to fire at a specific time. when dAtDate is blank
* or bogus we'll go for 10 seconds from now.
*
* @param sActions {string} // the 'type' of action, input or button or...
* @param sTitle {string} // title string for the notification
* @param sText {string} // body text for the notification
* @param dAtDate {object} // date object containing the fire time
* @param bWithoutCancelling {boolean} // then true will NOT cancel existing notifications first
*/
export function an_scheduleSingleLocalNotification(
sActions,
sTitle,
sText,
dAtDate,
bWithoutCancelling
) {
if (an_isLocalNotificationPluginValid()) {
if (typeof bWithoutCancelling === "undefined") {
bWithoutCancelling = true;
}
// compute a fire date and time
let dFireAt = new Date(dAtDate);
if (
typeof dFireAt === "undefined" ||
dFireAt.toString() === "Invalid Date"
) {
dFireAt = dateAdd(new Date(), 10, "secs");
}
// build the reminder, start with a basic no-action reminder
let oKatzerLNPluginReminder = {
id: new Date().getTime(),
trigger: { at: new Date(dFireAt) }, // MUST be a date object
text:
sText ||
"This is a test message scheduled to fire at " + dFireAt.toString(),
title: sTitle || "TESTING!",
data:
'{"rcls":"' +
applicationStateStore.getState().activeModule +
'","nid":"Test"}'
};
// add actions as indicated
switch (sActions) {
case ksLocalNotificationCategoryID_buttons_yes_no:
oKatzerLNPluginReminder.actions = ksLocalNotificationCategoryID_buttons_yes_no;
// install the listeners
cordova.plugins.notification.local.un(
ksLocalNotificationActionID_buttons_yes_no_ButtonID_yes,
handleLNResponse_yes
);
cordova.plugins.notification.local.on(
ksLocalNotificationActionID_buttons_yes_no_ButtonID_yes,
handleLNResponse_yes
);
cordova.plugins.notification.local.un(
ksLocalNotificationActionID_buttons_yes_no_ButtonID_no,
handleLNResponse_no
);
cordova.plugins.notification.local.on(
ksLocalNotificationActionID_buttons_yes_no_ButtonID_no,
handleLNResponse_no
);
break;
case ksLocalNotificationActionID_input:
oKatzerLNPluginReminder.actions = ksLocalNotificationCategoryID_input;
cordova.plugins.notification.local.un(
ksLocalNotificationActionID_input,
handleLNResponse_input
);
cordova.plugins.notification.local.on(
ksLocalNotificationActionID_input,
handleLNResponse_input
);
break;
default:
break;
}
// android can show the smallIcon in the actionbar
if (gsRunningOnPlatform.toLowerCase() === kPlatformandroid) {
oKatzerLNPluginReminder.smallIcon = "res://" + gsANAndroidPushIcon;
}
let aMultiRemindersForKatzerLNPlugin = [oKatzerLNPluginReminder];
if (aMultiRemindersForKatzerLNPlugin.length) {
pRunPromisesSerially(getTestKatzerActionGroupArray()).then(
() => {
if (!bWithoutCancelling) {
cordova.plugins.notification.local.cancelAll(
function scheduleAllRemindersViaKatzer() {
// setTimeout(cordova.plugins.notification.local.cancelAll(function scheduleAllRemindersViaKatzer() {
console.log(
"ANSLMH.an_sSLNFR - cancellation completed. Elapsed: " +
(new Date().getTime() - new Date().getTime()) / 1000 +
" secs"
);
console.log(
" ANSLMH.an_sSLNFR - scheduling >" +
aMultiRemindersForKatzerLNPlugin.length +
"< local reminders"
);
setLSInt(ksLocalMessagesActuallyScheduled, 0); // reset the count
goScheduledLocalMessages = {}; // purge our copy
cordova.plugins.notification.local.schedule(
aMultiRemindersForKatzerLNPlugin
);
}
);
} else {
console.log(
" ANSLMH.an_sSLNFR - scheduling >" +
aMultiRemindersForKatzerLNPlugin.length +
"< local reminders without cancelling"
);
cordova.plugins.notification.local.schedule(
aMultiRemindersForKatzerLNPlugin
);
}
},
() => {
console.error(
"ANSLMH.an_sSLNFR - Can't schedule local notifications, the local notification plugin is invalid"
);
}
);
} else {
console.error(
"ANSLMH.an_sSLNFR - Can't schedule local notifications, the local notification plugin is invalid"
);
}
}
}
/**
* getTestKatzerActionGroupArray
*
* returns an array of promises that are resolved when the katzer plugin
* finishes adding an action category. DO NOT LET THESE RUN IN PARALLEL, they'll
* overwrite each other.
*
* @returns {*[]} // an array of test promises
*/
export function getTestKatzerActionGroupArray() {
let aActionGroups = [];
aActionGroups.push(() => {
new Promise((resolve, reject) => {
if (an_isLocalNotificationPluginValid()) {
console.log("ANSLMH.aKAG - adding button category has begun");
cordova.plugins.notification.local.addActions(
ksLocalNotificationCategoryID_buttons_yes_no,
[
{
id: ksLocalNotificationActionID_buttons_yes_no_ButtonID_yes,
title: i18n.t("Yes")
},
{
id: ksLocalNotificationActionID_buttons_yes_no_ButtonID_no,
title: i18n.t("No")
}
],
() => {
console.log("ANSLMH.aKAG - adding button category has completed");
resolve("\nANSLMH.aKAG - did set buttons action group");
}
);
} else {
console.log(
"ANSLMH.aKAG - could not add the notification action groups, no plugin"
);
reject(
"ANSLMH.aKAG - FAILED to set action groups, plugin is not valid"
);
}
});
});
aActionGroups.push(() => {
new Promise((resolve, reject) => {
if (an_isLocalNotificationPluginValid()) {
console.log("ANSLMH.aKAG - adding input category has begun");
cordova.plugins.notification.local.addActions(
ksLocalNotificationCategoryID_input,
[
{
id: ksLocalNotificationActionID_input,
type: "input",
title: i18n.t("Reply"),
emptyText: i18n.t("Type message")
}
],
() => {
console.log("ANSLMH.aKAG - adding input category has completed");
resolve("\nANSLMH.aKAG - did set input action group");
}
);
} else {
console.log(
"ANSLMH.aKAG - could not add the notification action groups, no plugin"
);
reject(
"ANSLMH.aKAG - FAILED to set action groups, plugin is not valid"
);
}
});
});
return aActionGroups.reverse();
}
WARNING: IF YOU IGNORE THIS TEMPLATE, WE'LL IGNORE YOUR ISSUE. YOU MUST FILL THIS IN!
Provide a general summary of the issue.
Your Environment
cordova -v
): 7.1.0cordova platform ls
): android 6.3.0 ios 4.5.4Expected Behavior
iOS notification has action buttons or input
Actual Behavior
Notification appears as expected but without action buttons or input. Buttons/input appear on Android (8.1 tested, buttons/input do not appear on 4.4.4 but that's not a surprise)
Steps to Reproduce
Reproduce this issue; include code to reproduce, if relevant
This is a button notification (sorry about the indenting)
Context
nothing special, just let the notification fire and check the notification shade
Debug logs
logs don't show much...