Flutter yearly local notifications - android

I want to develop a birthday app and it should send a notification every year per person.
I am already using the 'flutter_local_notifications' package and it got the feature to periodically show a notification, but not yearly. At the moment I am just determine the next birthday of each person and everytime a user opens the app, the notifications are scheduled. But if somebody doesn't open up the app in a year, he won't be notificated.
Have anyone a solution for this?

Here is a workaround if you want to implement yearly notifications with 'flutter_local_notifications' package:
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
List<tz.TZDateTime> scheduledDateTimes = [];
int numberOfYears = 7; // Define how many years you want this notification to show
int notificationID = Random().nextInt(1000000);
DateTime startDate = DateTime.now(); // Define the starting date of this yearly notification
for (int i = 0; i < numberOfYears; i++) {
scheduledDateTimes.add(tz.TZDateTime(tz.local, date.year + i, date.month,
date.day);
}
scheduledDateTimes.asMap().forEach((index, dateTime) async {
await flutterLocalNotificationsPlugin.zonedSchedule(
int.parse("$notificationID$index"),
title,
'Notification title',
dateTime,
notificationDetails,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime);
});
Also, please take into consideration that number of local notifications you can schedule is limited to 50 for android, and 64 for iOS.

Related

Flutter repeated weekly notification

Actually i want to show weekly notification in flutter, i don't find a way to i'm asking here :-)
So in my app user can schedule timetable and got notification according to that.
And user can schedule notifcation for all 7 days of week(monday, tuesday ... sunday),
now i want to repeat these notification on weekly basis, so if user scheduled notification for monday so that notification will repeat on monday, and if it is scheduled for tuesday it will repeat on tuesday and so on.
static Future showWeeklyNotification({
required int id,
String? title,
String? body,
String? payload,
required int weekday,
required Time scheduleTime,
}) async => _notifications.zonedSchedule(
id,
title,
body,
_scheduleWeekly(scheduleTime , weekday, ),
await _notificationDetails(),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
);
static tz.TZDateTime _scheduleDaily(Time time){
final now = tz.TZDateTime.now(tz.local);
final scheduleDate = tz.TZDateTime(tz.local, now.year, now.month, now.day, time.hour, time.minute, time.second);
return scheduleDate.isBefore(now) ? scheduleDate.add(Duration(days: 1)) : scheduleDate;
}
static tz.TZDateTime _scheduleWeekly(Time time, weekDay){
tz.TZDateTime scheduleDate = _scheduleDaily(time);
print("hour");
print(time.hour);
print(time.minute);
print("weekday");
print(weekDay);
while(scheduleDate.weekday != weekDay){
scheduleDate = scheduleDate.add(const Duration(days: 1));
}
return scheduleDate;
}
I am using this code but it's not working, can anyone help me to find out what's wrong.
If i schedule it for today then it will work, but if i schedule it for next day or previous day
it seems to not work.
Thankyou in advance.

How to check freeTrialPeriod Expire Date InApp purchase in flutter

Implement InApp purchase(non-consumable) in flutter using flutter_inapp_purchase .
I have three plan 1 month, 6 month and 1 year, now i am checking is if 1 month plan then check transactionData and add 30 day to check expire date same for other 2 plan,
but problem is when user is on trial period then how can i check trial period expire date
List<String> storeItems = ['onemonth', 'sixmonth', 'oneyear'];
List<IAPItem> subscriptions = [];
List<PurchasedItem> purchasesSubscriptions = [];
StreamSubscription _purchaseUpdatedSubscription;
StreamSubscription _purchaseErrorSubscription;
StreamSubscription _conectionSubscription;
initPurchaseState(SportsProvider sportsProvider) async {
print("initPurchaseState");
await FlutterInappPurchase.instance.initConnection;
if (!mounted) return;
_conectionSubscription =
FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen((productItem) {
var data = jsonDecode(productItem.transactionReceipt);
int purchaseState = data["purchaseState"];
String productId = data["productId"];
String purchaseToken = data["purchaseToken"];
print("Data : ${data.toString()}, ${purchaseState}, ${productId}, ${purchaseToken}");
print('purchase-updated: $productItem');
FlutterInappPurchase.instance.finishTransaction(productItem);
});
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen((purchaseError) {
print('purchase-error: $purchaseError');
});
subscriptions =
await FlutterInappPurchase.instance.getSubscriptions(storeItems);
//print("subscriptions: ${subscriptions}");
//subscriptions.forEach((f){print("subscription : ${f.freeTrialPeriodAndroid}");});
subscriptions.forEach((f){print("subscriptionPeriodAndroid : ${f.subscriptionPeriodAndroid}");});
subscriptions.forEach((f){print("subscriptionPeriodAndroid : ${f.toString()}");});
subscriptions.forEach((f){print("subscriptionPeriodAndroid : ${f.originalJson}");});
//Here we check for 1 month subscription is available or not by passig productId and days
var isSubscribedForMonth = await FlutterInappPurchase.instance.checkSubscribed(sku:subscriptions[0].productId,duration: Duration(days: 30));
print(isSubscribedForMonth);
//Here we check for 1 month subscription is available or not by passig productId and days
var isSubscribedForSixMonth = await FlutterInappPurchase.instance.checkSubscribed(sku:subscriptions[1].productId,duration: Duration(days: 180));
print(isSubscribedForSixMonth);
//Same for one year
//But how can identify the current subscription is on trial period?
// code for already subscribed
}
Have any way to identify the the current period is trial or regular.
I have tried so may solution but not get any relevant solution for my question,
please help me for the problem
if any more clarification required then just comment

Getting "originalRequire is not a function" when using benCoding AlarmManager in Titanium mobile project

I am updating a Titanium mobile application which can schedule alarm notification for events, such that notification will pop up at the scheduled time.
Originally the mobile application is using a titanium module named as benCoding AlarmManager: https://github.com/benbahrenburg/benCoding.AlarmManager to schedule notification. However after I upgraded titanium SDK from 8.3.0 to 9.0.0, I found that there would be error starting the application if I killed the application before the notification scheduled time. For example, if I schedule an alarm notification at 8:00 and the application is not running in the background at 8:00. Although notification will pop up at 8:00, there will be error when starting the application.
E/TiExceptionHandler: (main) [333,333] <embedded>:19295
return originalRequire(moduleId);
^
TypeError: originalRequire is not a function
at global.require (<embedded>:19295:10)
at <embedded>:19555:3
at loadAsync (<embedded>:19481:5)
at _startSnapshot (<embedded>:19552:1)
at /ti.main.js:1:98
at Module._runScript (ti:/module.js:587:9)
at Module.load (ti:/module.js:106:7)
at Function.Module.runModule (ti:/module.js:74:9)
org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)
org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:174)
org.appcelerator.titanium.TiApplication.launch(TiApplication.java:791)
org.appcelerator.titanium.TiLaunchActivity.loadScript(TiLaunchActivity.java:98)
org.appcelerator.titanium.TiRootActivity.loadScript(TiRootActivity.java:480)
org.appcelerator.titanium.TiLaunchActivity.onResume(TiLaunchActivity.java:179)
org.appcelerator.titanium.TiRootActivity.onResume(TiRootActivity.java:499)
android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1446)
android.app.Activity.performResume(Activity.java:7939)
android.app.ActivityThread.performResumeActivity(ActivityThread.java:4195)
I included one of my example code on AlarmManager, which will schedule a notification after pressing a button. The notification will be pop up after 2 minutes and pressing the notification will create error message "originalRequire is not a function".
// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Ti.UI.setBackgroundColor('#000');
// Add this in so Titanium will add the permission for us.
Titanium.Media.vibrate();
// Add this so Titanium will add the permissions and links needed to play sounds
var sound = Titanium.Media.createSound();
// Bring in the module
var alarmModule = require('bencoding.alarmmanager');
// Create a new instance of the Alarm Manager
var alarmManager = alarmModule.createAlarmManager();
// Create our basic window to put our example buttons on
var win = Titanium.UI.createWindow({
title:'Tab 1', backgroundColor:'#fff', title:'Alarm Manager Tests'
});
var btn1 = Ti.UI.createButton({
title:"Alarm & Notify Basic", top:10, left:5, width: 150, height:75
});
win.add(btn1);
btn1.addEventListener('click', function(e){
scheduleAlert = function(id, title, content) {
id = parseInt(id);
var date = new Date();
alarmManager.cancelAlarmService(id);
// To resolve the problem mutiple alarm at the same time using Android alarmanager
var dateStr = "alarm" + date.getTime();
Ti.API.info("addAlarmService:"+ date.getFullYear() + ", " + date.getMonth() + "," + date.getDate() + "," + date.getHours() + ","+date.getMinutes() + ", "+date.getSeconds());
var hr = date.getHours();
var min = date.getMinutes() + 2;
var sec = date.getSeconds();
alarmManager.addAlarmService({
service : Ti.App.id + '.AlertServiceService',
requestCode : id,
//icon: Ti.Android.R.drawable.star_on, //Optional icon must be a resource id or url
year : date.getFullYear(),
month : date.getMonth(),
day : date.getDate(),
hour : hr,
minute : min,
second : sec
});
var ew = Ti.UI.createAlertDialog({
title : 'Info',
message : "The Service provided will be started at " + hr + ":" + min + ":" + sec,
buttonNames : [Ti.Android.currentActivity.getString(Ti.Android.R.string.ok)]
});
ew.show();
};
scheduleAlert(1, "Testing 123", "");
});
win.open();
I know that benCoding AlarmManager is a bit old and the last updated date is Jan 2018, however I do not know what alternatives can I use to generate notification same as AlarmManager in a Titanium application. Grateful if someone could provide advice for me on the error above or provide some alternatives on AlarmManager. Thanks.

FCM in android notification payload , event_time

i want to make the notification push on like maybe 5 minute after i run this http function. delete the event_time from the jsaon of notification i will receive the push notification that have timeline now, but if i hard code the event_time the time will show 50 year ago since epoch time , event i put 999 for the year it just increase by 2 year . i dint get it at all. then found Timestapm format in google and firebase so use it and the android got error whil parsing the json payload said cant fine field something . have any idea to format the Zulu RC399 time format?
pp.get('/sendCloudMessageReminderActivation', async (req, res) => {
const x = req.query.userUID;
const xstr = String(x);
const zxcv = admin.firestore().collection('user').doc(xstr);
const xoxo = await zxcv.get();
var today = new Date();
// today.setHours(today.getHours()+1);
today.setHours(today.getHours()+8);
// today.setFullYear(today.getFullYear()+50);
var xoxocode;
console.log(today+'saya saya sebelum cagbge');
// today = ISODateString(today);
const timestamp = admin.firestore.Timestamp.fromDate(today);
console.log(timestamp.nanoseconds +'siniiiiiiiiiiiiiiiiiiiii');
if (xoxo!==null) {
xoxocode= await xoxo.data().cloudMessagingToken;
const message = {
notification: {
title: 'your account is still in active state',
body: 'Tap here to check it out!'
},
android:{
priority:'high',
// important : 'MAX',
notification:{
notification_priority: "PRIORITY_MAX",
event_time: timestamp,// when ever i cahnge this event use ZULU RC339 format i still give my 50 year ago notification. i did my research but cant figure out how to do this ,
default_sound: true,
// notification_priority: PRIORITY_MAX
}
},
token: xoxocode
};
// res.status(200).send('authorized');
const respondfrommesage = admin.messaging().send(message);
console.log(respondfrommesage);
res.status(200).send('message send notification');
}
res.end();
});
Zulu is not a time format. It's a time zone. Zulu is just another name for UTC.
As per this article:
Another name for UTC Time is "Zulu" or "Z Time."
Now, about the timestamp value. If you are creating a Date object and use milliseconds or nanoseconds property of a date, it will always give you the difference in respective property type (mills/nano),
From the time you created the instance and starting time of UNIX which is 1 January 1970.
It has been 50 years as of 1st Jan, 2020. Hence the 50 year difference in the event_time.
If you have any other doubts let me know.

Titanium Change event not firing the first time with picker

I am making an iOS and Android app using Titanium Classic. I am fairly new to Titanium but I have some experience using Javascript. The app will have a window where the user and select from a picker an amount of time in hours and minutes. The selection will be saved and be used later to send a notification to the user that the time they selected is up. I am currently using Titanium's picker function with the type of "count down timer." However, I am having trouble getting the change event to work when the user selects a different time. It also will show the last selected time when I try going to a different window and entering the timer window again.
My question is how can I get the change event to fire the first time the user selects a different number?
In follow up to my question, is there a better way to save the picker selection for later use?
Here is the code for the picker:
var hours = 0;
var minutes = 1;
var win = Ti.UI.createWindow({
backgroundColor: '#A6B97B',
layout: 'horizontal'
});
var picker = Ti.UI.createPicker({
type:Ti.UI.PICKER_TYPE_COUNT_DOWN_TIMER,
top:2,
width: '50%',
height: '20%'
});
picker.addEventListener("change", function(e) {
Ti.App.Properties.setInt('countDownDuration', e.countDownDuration);
if (e.countDownDuration >= 3600000)
{
hours = Math.floor(Ti.App.Properties.getInt('countDownDuration')/3600000);
minutes = Math.floor(Ti.App.Properties.getInt('countDownDuration')/60000 - (hours*60));
}
else {
minutes = Math.floor(Ti.App.Properties.getInt('countDownDuration')/60000);
hours = 0;
}
});
var doneBtn = Ti.UI.createButton({
title : 'Get Value',
height : '15%',
width : '30%'
});
doneBtn.addEventListener('click', function() {
// get value
if(hours > 0){
alert('You set the time estimate to ' + hours + ' hours and ' + minutes+ ' minutes');
}
else {
alert('You set the time estimate to ' + minutes + ' minutes');
}
});
If anyone has any advice on how to get the change event to fire the first time, I would really appreciate it. Also, if you know a better way to accomplish saving data from the picker for use later, that would be helpful as well.
Thanks!
Jessica

Categories

Resources