display dynamic data in flutter local notification - android-notifications

How do I display Dynamic data (such a DateTime ) using flutter local notification plugin ?
I think that is possible by using repeatNotification (periodicallyShow) but when I use DateTime.now() but in the next time, the same value is returned.
Future<void> repeatNotification() async {
String time = tz.TZDateTime.now(tz.local).minute.toString();
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('megadars_daily',
'example',
channelDescription: 'example',
priority: Priority.high,
when: 0,
ongoing: true,
autoCancel: false,
importance: Importance.high,
usesChronometer: true,
showWhen: false,
channelShowBadge: false);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.cancel(0);
await flutterLocalNotificationsPlugin.periodicallyShow(
5,
'example',
time+''+This value must be dynamic, which it is not. <<',
RepeatInterval.everyMinute,
platformChannelSpecifics,
androidAllowWhileIdle: true,
payload: 'example');
}

Related

How to update session user properties after update user model

I need to update the logged in user name and email.
The problem is that when I update them to the DB (MongoDB), session object properties do not change.
This is the code to make the problem clear:
const { data: session } = useSession();
const toast = useToast();
const { colorMode } = useColorMode();
const [name, setName] = useState(session?.user.name);
const [email, setEmail] = useState(session?.user.email);
const formSubmit = async (actions: any) => {
actions.setSubmitting(false);
const res = await axios.post("/api/update", {name, email})
.then(() => {
toast({description: "Info successfully updated", status: 'success', position: 'bottom-right', isClosable: true, duration: 3000})
})
.catch((error) => {
toast({description: error.response.data.error, status: 'error', position: 'bottom-right', isClosable: true, duration: 3000})
});
};
The update successfully occurs on MongoDB, however the session object remains the same.
How can I tell nextjs to update session object as well?

How to store the value retrieved from Firebase into a variable Flutter

I'm trying to retrieve the data(customer name, customer ID)from the firebase and store it into the variables. After that, I want to store the variables data into another firebase path location.
I'm able to call the snapshot and print it but I just can't save the data from firebase into the variables.
CollectionReference orderInfo =
FirebaseFirestore.instance.collection('orderInfo');
final user = FirebaseAuth.instance.currentUser;
String cusName;
String add;
void getNameAddress() async {
final doc = await FirebaseFirestore.instance
.collection('users')
.doc(user.uid)
.get();
cusName = doc['name'];
add = doc['address1'] + '' + doc['address2'] + '' + doc['address3'];
}
Future initializeOrder(BuildContext ctx) {
getNameAddress();
return orderInfo.doc(user.uid + 'order').set({
'orderID': '',
'cusID': user.uid,
'cusName': cusName,
'cusAdd': add,
'clID': '',
'clName': null,
'price': null,
'selectedDate': null,
'serviceSelected': null,
'typeOfService': 'Not selected yet',
});
}
The intializeOrder() is the function that I use to store the data in another path.
How should I solve it ?
Since the getNameAddress() function is async and the Firestore set() method is asynchronous, you need to make your initializeOrder() function async and use await when calling getNameAddress(), as follows:
Future<void> initializeOrder(BuildContext ctx) async {
await getNameAddress();
return orderInfo.doc(user.uid + 'order').set({
'orderID': '',
'cusID': user.uid,
'cusName': cusName,
'cusAdd': add,
'clID': '',
'clName': null,
'price': null,
'selectedDate': null,
'serviceSelected': null,
'typeOfService': 'Not selected yet',
});
}

How to use encryption and decryption script for copy and paste for transit of password?

I use the script in web
But error in edge browser console
At const key = await .... expect “;”
How to use this script correctly?
I have no chrome browser in another computer and only expect to use default browser edge in window 10
I use for password transit through USB storage
const encoder = new TextEncoder();
const toBase64 = buffer =>
btoa(String.fromCharCode(...new Uint8Array(buffer)));
const PBKDF2 = async (
password, salt, iterations,
length, hash, algorithm = 'AES-CBC') => {
keyMaterial = await window.crypto.subtle.importKey(
'raw',
encoder.encode(password),
{name: 'PBKDF2'},
false,
['deriveKey']
);
return await window.crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: encoder.encode(salt),
iterations,
hash
},
keyMaterial,
{ name: algorithm, length },
false, // we don't need to export our key!!!
['encrypt', 'decrypt']
);
}
const salt = window.crypto.getRandomValues(new Uint8Array(16));
const iv = window.crypto.getRandomValues(new Uint8Array(16));
const plain_text = encoder.encode("That is our super secret text");
const key = await PBKDF2('my password', salt, 100000, 256, 'SHA-256');
const encrypted = await window.crypto.subtle.encrypt(
{name: "AES-CBC", iv },
key,
plain_text
);
console.log({
salt: toBase64(salt),
iv: toBase64(iv),
encrypted: toBase64(encrypted),
concatennated: toBase64([
...salt,
...iv,
...new Uint8Array(encrypted)
])
});
In the script, the keyword var is missing in the definition of keyMaterial. Edge then generates the error message Uncaught (in promise) ReferenceError: keyMaterial is not defined at PBKDF2... Apart from that the script is executed on my machine (Edge version 90.0.818.46).
Another problem may be an older Edge version. Edge (meanwhile Chromium-based) supports top-level-awaits as of version 89, in earlier versions the script has to be encapsulated in an asynchronous top-level function (see also here), e.g.
const main = async () => {
const encoder = new TextEncoder();
const toBase64 = buffer =>
btoa(String.fromCharCode(...new Uint8Array(buffer)));
const PBKDF2 = async (
password, salt, iterations,
length, hash, algorithm = 'AES-CBC') => {
var keyMaterial = await window.crypto.subtle.importKey(
'raw',
encoder.encode(password),
{name: 'PBKDF2'},
false,
['deriveKey']
);
return await window.crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: encoder.encode(salt),
iterations,
hash
},
keyMaterial,
{ name: algorithm, length },
false, // we don't need to export our key!!!
['encrypt', 'decrypt']
);
}
const salt = window.crypto.getRandomValues(new Uint8Array(16));
const iv = window.crypto.getRandomValues(new Uint8Array(16));
const plain_text = encoder.encode("That is our super secret text");
const key = await PBKDF2('my password', salt, 100000, 256, 'SHA-256');
const encrypted = await window.crypto.subtle.encrypt(
{name: "AES-CBC", iv },
key,
plain_text
);
console.log({
salt: toBase64(salt),
iv: toBase64(iv),
encrypted: toBase64(encrypted),
concatennated: toBase64([
...salt,
...iv,
...new Uint8Array(encrypted)
])
});
}
(async () => {
await main();
})();
Newer Edge versions are based on Chronium, under which the script also runs for earlier versions (tested for v85). I couldn't do a test for Edge versions before the Chromium switch, because I don't have a correspondingly old version. If you use one, you would have to test this in your environment.

Flutter: Push notifications even if the app is closed

I have built an application with flutter that works like a reminder.
How can I display notifications to the user even though the app is closed?
For reminders i would recomend Flutter Local Notifications Plugin. It has a powerful scheduling api. From the documentation of local notification:
Scheduling when notifications should appear - Periodically show a
notification (interval-based) - Schedule a notification to be shown
daily at a specified time - Schedule a notification to be shown weekly
on a specified day and time - Ability to handle when a user has tapped on a notification when the app is the foreground, background or terminated
And for push notification, you can use Firebase Cloud Messaging
or one signal plugin or you can implement natively through platform-channels
Edit: You can also fire notifications according to specific conditions even if the app is terminated. This can be achevied by running dart code in the background. Quoting from the official faq:
Can I run Dart code in the background of an Flutter app? Yes, you can
run Dart code in a background process on both iOS and Android. For
more information, see the Medium article Executing Dart in the
Background with Flutter Plugins and Geofencing.
I have found a solution to this problem. We just have to register the Local Notification Plugin in the Application class.
First Create a class FlutterLocalNotificationPluginRegistrant, I have created this in Kotlin.
class FlutterLocalNotificationPluginRegistrant {
companion object {
fun registerWith(registry: PluginRegistry) {
if (alreadyRegisteredWith(registry)) {
Log.d("Local Plugin", "Already Registered");
return
}
FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
Log.d("Local Plugin", "Registered");
}
private fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
val key = FlutterLocalNotificationPluginRegistrant::class.java.canonicalName
if (registry.hasPlugin(key)) {
return true
}
registry.registrarFor(key)
return false
}
}}
Now create a Application class extending FlutterApplication and implement PluginRegistry.PluginRegistrantCallback.
class Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
}
override fun registerWith(registry: PluginRegistry?) {
if (registry != null) {
FlutterLocalNotificationPluginRegistrant.registerWith(registry)
}
}}
and register the Application class in the AndroidManifest.xml
<application
android:name="com.packagename.Application"/>
All done. Now write a function to show notification and call it from the background handler method of Firebase messaging.
Future _showNotificationWithDefaultSound(String title, String message) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'channel_id', 'channel_name', 'channel_description',
importance: Importance.Max, priority: Priority.High);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
'$title',
'$message',
platformChannelSpecifics,
payload: 'Default_Sound',
);
}
and call it like this.
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
if (message['data'] != null) {
final data = message['data'];
final title = data['title'];
final body = data['message'];
await _showNotificationWithDefaultSound(title, message);
}
return Future<void>.value();
}
I have also faced this issue, So these are my learnings
In my Case : i am able to get notification in App-Resume or App-background state, but in App-Close state, I am not receiving notifification.
In this case our notification body was :
{notification: {body: null, title: null}, data: {body: hello, title: world}}
To Receive Notification in App-Closed state we changed notification to
{notification: {body: abc, title: abc}, data: {url: string, body: string, title: string}}
You can use scheduled notifications in flutter.
var scheduledNotificationDateTime =
new DateTime.now().add(new Duration(seconds: 5));
var androidPlatformChannelSpecifics =
new AndroidNotificationDetails('your other channel id',
'your other channel name', 'your other channel description');
var iOSPlatformChannelSpecifics =
new IOSNotificationDetails();
NotificationDetails platformChannelSpecifics = new
NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.schedule(
0,
'scheduled title',
'scheduled body',
scheduledNotificationDateTime,
platformChannelSpecifics);
For those who are using the latest version around 2.2 just call the firebaseMessageInstance
FirebaseMessaging.instance.getInitialMessage().then((message) =>
message.messageId.isNotEmpty
? print('we can now navigate to specific screen')
: print('there is no new notification so default screen will be shown when application start from terminated state'));
Don't forget to call the
Navigator.push(
context, MaterialPageRoute(builder: (context) => YourScreenName()));
when message.messageId.isNotEmpty
upvote if you like this approach thanks have a good coding day
If you do not need to connect to the Internet, you can use this packages flutter local notification && flutter native timezone
after add the package to pubspace.ymal
add this code to android/app/src/main/AndroidManifest.xml
<activity
android:showWhenLocked="true"
android:turnScreenOn="true">
also in ios folder open if you used swift Runner/AppDelegate.swift in function didFinishLaunchingWithOptions add
if #available(iOS 10.0, *) {UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate}
if you used Object-C Runner/AppDelegate.m in function didFinishLaunchingWithOptions add
if (#available(iOS 10.0, *)) {[UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
}
after that you should add app-icon to drawable folder
then import the packages import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:timezone/data/latest.dart' as tz; import 'package:timezone/timezone.dart' as tz; in file dart create and add
class NotifyHelper {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
String selectedNotificationPayload = '';
final BehaviorSubject<String> selectNotificationSubject =
BehaviorSubject<String>();
initializeNotification() async {
tz.initializeTimeZones();
_configureSelectNotificationSubject();
await _configureLocalTimeZone();
// await requestIOSPermissions(flutterLocalNotificationsPlugin);
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('appicon');
final InitializationSettings initializationSettings =
InitializationSettings(
iOS: initializationSettingsIOS,
android: initializationSettingsAndroid,
);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: (String? payload) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
selectNotificationSubject.add(payload!);
},
);
}
displayNotification({required String title, required String body}) async {
print('doing test');
var androidPlatformChannelSpecifics = const AndroidNotificationDetails(
'your channel id', 'your channel name', 'your channel description',
importance: Importance.max, priority: Priority.high);
var iOSPlatformChannelSpecifics = const IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
title,
body,
platformChannelSpecifics,
payload: 'Default_Sound',
);
}
// this is the scheduled notification
// Task is a model class have a data item like title, desc, start time and end time
scheduledNotification(int hour, int minutes, Task task) async {
await flutterLocalNotificationsPlugin.zonedSchedule(
task.id!,
task.title,
task.note,
//tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5)),
_nextInstanceOfTenAM(hour, minutes),
const NotificationDetails(
android: AndroidNotificationDetails(
'your channel id', 'your channel name', 'your channel description'),
),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
matchDateTimeComponents: DateTimeComponents.time,
payload: '${task.title}|${task.note}|${task.startTime}|',
);
}
tz.TZDateTime _nextInstanceOfTenAM(int hour, int minutes) {
final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
tz.TZDateTime scheduledDate =
tz.TZDateTime(tz.local, now.year, now.month, now.day, hour, minutes);
if (scheduledDate.isBefore(now)) {
scheduledDate = scheduledDate.add(const Duration(days: 1));
}
return scheduledDate;
}
void requestIOSPermissions() {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
}
Future<void> _configureLocalTimeZone() async {
tz.initializeTimeZones();
final String timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
tz.setLocalLocation(tz.getLocation(timeZoneName));
}
/* Future selectNotification(String? payload) async {
if (payload != null) {
//selectedNotificationPayload = "The best";
selectNotificationSubject.add(payload);
print('notification payload: $payload');
} else {
print("Notification Done");
}
Get.to(() => SecondScreen(selectedNotificationPayload));
} */
//Older IOS
Future onDidReceiveLocalNotification(
int id, String? title, String? body, String? payload) async {
// display a dialog with the notification details, tap ok to go to another page
/* showDialog(
context: context,
builder: (BuildContext context) => CupertinoAlertDialog(
title: const Text('Title'),
content: const Text('Body'),
actions: [
CupertinoDialogAction(
isDefaultAction: true,
child: const Text('Ok'),
onPressed: () async {
Navigator.of(context, rootNavigator: true).pop();
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Container(color: Colors.white),
),
);
},
)
],
),
);
*/
Get.dialog( Text(body!));
}
//I used Get package Get here to go screen notification
void _configureSelectNotificationSubject() {
selectNotificationSubject.stream.listen((String payload) async {
debugPrint('My payload is ' + payload);
await Get.to(() => NotificationScreen(payload));
});
}
}
use object from this class and call the scheduledNotificationmethod

Jest timeout testing Koa route

I am starting with Jest for testing our API. However, the moment I add my second test, everything falls apart with a timeout exception.
Here's my code:
const server = require('../server')
const request = require('supertest')
const path = require("path")
const fs = require("fs")
const config = require('../knexfile.js')
const knex = require('knex')(config.development)
beforeAll(async () => {
let file = fs.readFileSync(path.join(__dirname, '..', 'galaxycard.sql'), 'utf8')
await knex.raw(file)
await knex.migrate.latest()
})
afterAll(async () => {
await knex.raw(`
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO public;
`)
server.close()
})
describe("test 1", () => {
it("should not be able to add a payment for user without credit", async () => {
let response = await request(server)
.post('/v1/hampers')
.set('Content-Type', 'application/json')
.send({
entity_type: 'utility',
latitude: 1,
longitude: 1,
comment: null,
user_id: new Date().getTime(),
amount: -200,
entity_id: 1,
processed: false
})
expect(response.status).toEqual(402)
})
})
describe("test 2", () => {
let userId
beforeEach(async () => {
userId = new Date().getTime()
let response = await request(server)
.post('/v1/hampers')
.set('Content-Type', 'application/json')
.send({
entity_type: 'credit',
latitude: 0,
longitude: 0,
user_id: userId,
amount: 5000,
entity_id: 1,
processed: true
})
expect(response.status).toEqual(200)
expect(JSON.parse(response.text)).toHaveProperty('uuid')
})
it("have hampers", async () => {
let response = await request(server)
.post('/v1/hampers')
.set('Content-Type', 'application/json')
.send({
entity_type: 'utility',
latitude: 1,
longitude: 1,
comment: null,
user_id: userId,
amount: -200,
entity_id: 1,
processed: false
})
expect(response.status).toEqual(200)
expect(JSON.parse(response.text)).toHaveProperty('uuid')
})
})
Jest keeps dying with:
Timeout - Async callback was not invoked within the 5000ms timeout
specified by jest.setTimeout.
Another weird issue is that Jest doesn't exit after the tests have run, even though I use server.close.
The second issue (seeming to hang after the test run) is probably caused by the lack of knex.destroy() in your afterAll. I can speak to the first problem after seeing your route definition.

Resources