Send push notifications in different languages using FCM - flutter

I've added FCM in my Flutter app and it works, but I can't find a way to send notifications in different languages.
I saw that you can set the conditions for the language on the Firebase console when sending a new notification, but I'm not quite sure how it works. I would like to know if I need to add something to my code to make it work.
Here's the code I have:
push_notification_service.dart
import 'package:firebase_messaging/firebase_messaging.dart';
enum AppState {
foreground,
background,
terminated,
}
class PushNotificationsManager {
PushNotificationsManager._();
factory PushNotificationsManager() => _instance;
static final PushNotificationsManager _instance = PushNotificationsManager._();
Future<void> init() async {
await _setFCMToken();
_configure();
}
_setFCMToken() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
badge: true,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
String? token = await messaging.getToken();
print('FirebaseMessaging token: $token');
}
}
void _configure() async {
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
_showForegroundNotificationInAndroid(message);
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
_handleNotification(message: message.data, appState: AppState.foreground);
});
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
_handleNotification(message: initialMessage.data, appState: AppState.terminated);
}
}
void _showForegroundNotificationInAndroid(RemoteMessage message) async {}
void _handleNotification({
Map<String, dynamic>? message,
AppState? appState,
}) async {
print('PushNotificationsManager: _handleNotification ${message.toString()} ${appState.toString()}');
}
}
and in main.dart I have:
initState(){
super.initState();
PushNotificationsManager().init();
}
Do I need to use flutter_analytics package?

Related

how to disable push notifications by condition in Flutter?

I have an application, I want to send notifications only to authorized users,
authorization occurs by token if the token is empty, then the user is not authorized, for authorization and storing the token I use the shared_pref package. How can I disable notifications if the user is not logged in?
Token validation is only done in MyAppState notifications I need to disable in the same place
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await Permission.notification.request();
if(Constants.USER_TOKEN.isEmpty) {
FirebaseMessaging.instance.setAutoInitEnabled(false);
}
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
if (navKey.currentState != null) {
if(Constants.USER_TOKEN.isNotEmpty) {
navKey.currentState!.push(MaterialPageRoute(
builder: (context) => NotificationScreen()));
}
print('Message');
}
}
await _messaging.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification!.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: '#mipmap/ic_launcher',
),
),
);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage? message) {
print("On message opened app: ${message?.data}}");
if (navKey.currentState != null) {
if(Constants.USER_TOKEN.isNotEmpty) {
navKey.currentState!.push(MaterialPageRoute(
builder: (context) => const NotificationScreen()));
}
}
});
var initializationSettingsAndroid =
const AndroidInitializationSettings('#drawable/ic_notification');
var initializationSettingsIOS = const DarwinInitializationSettings();
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
await _messaging.requestPermission();
String? token = await _messaging.getToken();
if (token != null) {
print("FIREBASE TOKEN $token");
} else {
print("CANNOT TAKE FIREBASE TOKEN");
}
if (Platform.isIOS) {
var APNS = await _messaging.getAPNSToken();
print('APNS: $APNS');
}
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
getToken() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
Constants.USER_TOKEN = pref.getString('login') ?? "";
});
}
#override
void didChangeDependencies() async {
super.didChangeDependencies();
await getToken();
}
Use deleteToken which invalidates the current token and getToken again to get a new one when enabling.
getToken() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
Constants.USER_TOKEN = pref.getString('login') ?? "";
});
if(Constants.USER_TOKEN.isEmpty()){
// delete firebase token
}else{
// get firebase token
}
}

Firebase Push Notification is Not working Properly

i have implemented firebase push notification in my project with payload json,
I have done all the configurations and now when i click on the notification, it works sometimes perfectly but sometimes the redirection just doesn't work, let's say if i click the notification 10 times, it redirects to the desired page for 4 times and rest 6 times, its taking me to home screen. I am sharing my code below.
Main File
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
await Firebase.initializeApp();
await SharedPref.initialize();
initilizeCamera();
initializeDb();
FlutterError.onError = (error) {
FirebaseCrashlytics.instance.recordFlutterFatalError(error);
};
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(
const ProviderScope(child: MyApp()),
);
});
await pushNotificationToken();
/// Get initial message
await FirebaseMessaging.instance.getInitialMessage();
notificationActions(
action: (RemoteMessage? message) {
if (kDebugMode) {
if (message?.notification != null) {
}
}
if (message != null) {
notificationAction(message: message);
}
},
localNotification: true,
localNotificationAction: (payload) {
if (kDebugMode) {
}
notificationAction(payload: payload);
});
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
statusBarColor: Colors.white,
));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return KeyboardDismissOnTap(
child: GetMaterialApp(
theme: appThemeData,
debugShowCheckedModeBanner: false,
title: 'XYZ',
// Start the app with the "/" named route. In this case, the app starts
// on the FirstScreen widget.
initialRoute: '/',
initialBinding:XYZBindings(),
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => const XYZScreen(),
}),
);
}
}
Firebase Notification Code
/// Firebase messaging instance
FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
/// Get firebase notification instance
FirebaseMessaging get firebaseMessagingInstance => _firebaseMessaging;
/// Firebase push notification token
Future<String?> pushNotificationToken() async =>
_firebaseMessaging.getToken().then((value) {
Log.w('FCM TOKEN :: $value');
return value;
});
/// When user clicks on the notification
void notificationActions({
#required Function(RemoteMessage?)? action,
bool localNotification = false,
Function(Map<String, dynamic>)? localNotificationAction,
}) {
/// Make sure localNotification is Not Null
if (localNotification) {
assert(localNotificationAction != null);
}
if (Platform.isIOS) {
_requestPermissions();
}
if (localNotification) {
FlutterLocalNotificationHelper().initializeSettings(
actionCallback: localNotificationAction,
);
}
/// Get initial message
_firebaseMessaging.getInitialMessage().then((RemoteMessage? message) {
action!(message);
});
/// On Message
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
if (localNotification) {
await FlutterLocalNotificationHelper().showNotificationWithDefaultSound(
title: message.notification?.title,
body: message.notification?.body,
payload: jsonEncode(message.data),
);
}
});
/// On Message open app
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
action!(message);
});
}
/// Request permission for iOS
void _requestPermissions() {
_firebaseMessaging.requestPermission(
provisional: true,
);
}
Local Notification Page
/// Helper class for local notifications
class FlutterLocalNotificationHelper {
/// Constructor
factory FlutterLocalNotificationHelper() => _instance;
FlutterLocalNotificationHelper._();
/// Flutter LocalNotification Helper instance
static final FlutterLocalNotificationHelper _instance =
FlutterLocalNotificationHelper._();
/// Flutter LocalNotification for iOS Category
static const String darwinNotificationCategory = 'plainCategory';
/// Notification plugin
late FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin;
/// Flutter LocalNotifications Plugin
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
/// Request local notification
Future<void> requestLocalNotification() async {
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
}
/// local notification plugin callback
late Function(Map<String, dynamic>) _localNotificationCallback;
/// Initialize local notifications
Future<void> initializeSettings({
#required Function(Map<String, dynamic>)? actionCallback,
}) async {
if (actionCallback != null) {
_localNotificationCallback = actionCallback;
}
/// initialize settings for => Android
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
/// initialize settings for => iOS
const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
);
/// Initialize settings for both => Android / iOS
const InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
/// Flutter local notification plugin
_flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Local notification plugin initialize
await _flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) {
if (response.payload != null) {
_localNotificationCallback(json.decode(response.payload!));
}
},
);
/// On notification click
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await _flutterLocalNotificationsPlugin
.getNotificationAppLaunchDetails();
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
await onSelectNotification(
notificationAppLaunchDetails?.notificationResponse.toString(),
);
}
}
/// WHEN USER CLICKS TO NOTIFICATION
Future<void> onSelectNotification(String? payload) async {
if (payload != null) {
final Map<String, dynamic> payloadJson =
jsonDecode(payload) as Map<String, dynamic>;
_localNotificationCallback(payloadJson);
}
}
/// SHOW LOCAL NOTIFICATION
/// 'your channel id', 'your channel name', IS NOT NEEDED
Future<void> showNotificationWithDefaultSound({
#required String? title,
#required String? body,
#required String? payload,
}) async {
/// Android notification details
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your channel id',
'your channel name',
importance: Importance.max,
priority: Priority.high,
color: AppColors.red,
icon: '#mipmap/ic_launcher',
);
/// iOS Notification details
const DarwinNotificationDetails iOSPlatformChannelSpecifics =
DarwinNotificationDetails(
categoryIdentifier: darwinNotificationCategory,
presentSound: true,
presentAlert: true,
badgeNumber: 0,
);
/// Notification platforms details
const NotificationDetails platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics,
);
/// Show notification
await _flutterLocalNotificationsPlugin.show(
0,
title,
body,
platformChannelSpecifics,
payload: payload,
);
}
}
Notifications Action page
void notificationAction(
{RemoteMessage? message, Map<String, dynamic>? payload}) {
The redirection is written here.
}
please let me know that why sometimes the redirection works and sometimes not.

Firebase Messaging - Null check operator used on a null value?

import 'dart:developer';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../export.dart';
class FirebaseNotificationManager {
FirebaseNotificationManager._privateConstructor();
static final FirebaseNotificationManager _instance = FirebaseNotificationManager._privateConstructor();
factory FirebaseNotificationManager() {
return _instance;
}
init() async {
// add firebase notification permission
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: true,
provisional: false,
sound: true,
);
if (await Permission.notification.request().isGranted) {
try {
// Either the permission was already granted before or the user just granted it.
FirebaseMessaging.onBackgroundMessage(_messageHandler);
_firebaseMessagingListener();
String? deviceToken = await FirebaseMessaging.instance.getToken();
logger.i(deviceToken);
} catch (e) {
logger.i(e);
}
}
}
/// must call it from view after getContext is initialized to show dialog message
checkAndroid() async {
if (!(await Permission.notification.request().isGranted) && GetPlatform.isAndroid) {
showOptionsDialog(
text: 'إذا كنت ترغب في تلقي الاشعارات ،برجاء اعطاء إذن الاشعارات في الإعدادات وإعادة تشغيل التطبيق',
yesFunction: (context) async {
openAppSettings();
});
}
}
// execute if app in background
Future<void> _messageHandler(RemoteMessage message) async {
// Data notificationMessage = Data.fromJson(message.data);
log('notification from background : ${message.toMap()}');
}
// execute if app in foreground
void _firebaseMessagingListener() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
logger.i('Got a message whilst in the foreground!');
logger.i('Message data: ${message.data}');
if (message.notification != null) {
logger.i('Message also contained a notification: ${message.notification!.toMap()}');
logger.i('Message also contained a notification: ${message.toMap()}');
// that means new message
try {
Get.snackbar(message.notification!.title.toString(), message.notification!.body.toString(),
duration: Duration(seconds: 6),
backgroundColor: Theme.of(Get.context!).cardColor,
barBlur: 10,
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(8));
} catch (e) {
logger.i(e);
}
}
});
}
}
As per the documentation, you need to put the onBackgroundMessage function outside of a class, at the top of your file as a top-level function. See Firebase messaging example for implementation.
source
file became:
import 'dart:developer';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../export.dart';
init() async {
// add firebase notification permission
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: true,
provisional: false,
sound: true,
);
if (await Permission.notification.request().isGranted) {
try {
// Either the permission was already granted before or the user just granted it.
FirebaseMessaging.onBackgroundMessage(_messageHandler);
_firebaseMessagingListener();
String? deviceToken = await FirebaseMessaging.instance.getToken();
logger.i(deviceToken);
} catch (e) {
logger.i(e);
}
}
}
/// must call it from view after getContext is initialized to show dialog message
checkAndroid() async {
if (!(await Permission.notification.request().isGranted) && GetPlatform.isAndroid) {
showOptionsDialog(
text: 'إذا كنت ترغب في تلقي الاشعارات ،برجاء اعطاء إذن الاشعارات في الإعدادات وإعادة تشغيل التطبيق',
yesFunction: (context) async {
openAppSettings();
});
}
}
// execute if app in background
Future<void> _messageHandler(RemoteMessage message) async {
// Data notificationMessage = Data.fromJson(message.data);
log('notification from background : ${message.toMap()}');
}
// execute if app in foreground
void _firebaseMessagingListener() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
logger.i('Got a message whilst in the foreground!');
logger.i('Message data: ${message.data}');
if (message.notification != null) {
logger.i('Message also contained a notification: ${message.notification!.toMap()}');
logger.i('Message also contained a notification: ${message.toMap()}');
// that means new message
try {
Get.snackbar(message.notification!.title.toString(), message.notification!.body.toString(),
duration: Duration(seconds: 6),
backgroundColor: Theme.of(Get.context!).cardColor,
barBlur: 10,
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(8));
} catch (e) {
logger.i(e);
}
}
});
}

How to display notification in app in flutter

I'm trying to display the background and foreground notification in flutter using flutter_local_notifications package. here is my firebase class code
class FirebaseMessagingService {
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
IOSInitializationSettings? _initializationSettingsIOS;
AndroidInitializationSettings? _initializationSettingsAndroid;
AndroidNotificationDetails? _androidLocalNotificationDetails;
AndroidNotificationChannel? androidNotificationchannel;
static FirebaseMessagingService? _messagingService;
NotificationDetails? _androidNotificationDetails;
InitializationSettings? _initializationSettings;
//NotificationNavigationClass _notificationNavigationClass = NotificationNavigationClass();
NotificationAppLaunchDetails? _notificationAppLaunchDetails;
bool? _didNotificationLaunchApp;
static FirebaseMessaging? _firebaseMessaging;
FirebaseMessagingService._createInstance();
factory FirebaseMessagingService() {
// factory with constructor, return some value
if (_messagingService == null) {
_messagingService = FirebaseMessagingService
._createInstance(); // This is executed only once, singleton object
_firebaseMessaging = _getMessagingService();
}
return _messagingService!;
}
static FirebaseMessaging _getMessagingService() {
return _firebaseMessaging ??= FirebaseMessaging.instance;
}
Future<String?> getToken() {
return _firebaseMessaging!.getToken();
}
Future initializeNotificationSettings() async
{
NotificationSettings? settings = await _firebaseMessaging
?.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (settings?.authorizationStatus == AuthorizationStatus.authorized) {
print('User granted permission');
} else
if (settings?.authorizationStatus == AuthorizationStatus.provisional) {
print('User granted provisional permission');
} else {
print('User declined or has not accepted permission');
}
androidNotificationchannel = const AndroidNotificationChannel(
NOTIFICATION_ID, // id
NOTIFICATION_TITLE, // title
description: NOTIFICATION_DESCRIPTION,
// description
importance: Importance.max,
);
//
await _flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(androidNotificationchannel!);
if (Platform.isIOS) {
//configure local notification for ios
await _initializeIosLocalNotificationSettings();
}
else {
//configure local notification for android
await _initializeAndroidLocalNotificationSettings();
}
}
Future<void> _initializeIosLocalNotificationSettings() async
{
_initializationSettingsIOS = const IOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false
);
_initializationSettings = InitializationSettings(
iOS: _initializationSettingsIOS
);
}
Future<void> _initializeAndroidLocalNotificationSettings() async
{
_initializationSettingsAndroid =
const AndroidInitializationSettings('mipmap/ic_launcher');
_initializationSettings = InitializationSettings(
android: _initializationSettingsAndroid,
);
_androidLocalNotificationDetails =
const AndroidNotificationDetails(
LOCAL_NOTIFICATION_ID,
LOCAL_NOTIFICATION_TITLE,
channelDescription: LOCAL_NOTIFICATION_DESCRIPTION,
importance: Importance.max,
priority: Priority.high);
_androidNotificationDetails =
NotificationDetails(android: _androidLocalNotificationDetails);
//This will execute when the app is open and in foreground
void foregroundNotification() {
try {
_showLocalNotification(localNotificationId: DateTime
.now()
.hour + DateTime
.now()
.minute + DateTime
.now()
.second,
notificationData: message?.data,
messageTitle:message?.notification?.title ,
messageBody: message?.notification?.body,
);
} catch (error) {
log("error");
}
});
}
void _showLocalNotification(
{int? localNotificationId, Map<String, dynamic>? notificationData,String? messageTitle,String? messageBody}) async
{
if (notificationData != null) {
log("Notification Data:${notificationData}");
await _flutterLocalNotificationsPlugin.show(
localNotificationId ?? 0, notificationData["title"]??messageTitle,
notificationData["body"]??messageBody,
_androidNotificationDetails,
payload: jsonEncode(notificationData));
}
}
//This will excute when the app is in background but not killed and tap on that notification
void backgroundTapNotification() {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage? message) async {
try {
RemoteMessage? terminatedMessage = await _firebaseMessaging
?.getInitialMessage();
} catch (error) {
log("error");
}
});
}
}
and calling it in splash screen
#override
void initState() {
super.initState();
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 500));
heartbeatAnimation =
Tween<double>(begin: 100.0, end: 250.0).animate(controller);
controller.forward().whenComplete(() {
controller.reverse();
});
void _setNotifications() async {
FirebaseMessagingService().foregroundNotification();
FirebaseMessagingService().backgroundTapNotification();
}
await FirebaseMessagingService().initializeNotificationSettings();
_setNotifications();
}
When i close the app and hit the API notification is displaying on background, but when i open the app and hit the API notification is not displaying, nor foreground and not on background.
please help me to get out from this problem.

flutter_background_service not receiving updates

I'm using awesome_notifications and flutter_background_service in conjunction to update some app state when receiving data notifications from FirebaseMessaging. As noted in the awesome_notifications, the background message handler must be a top-level function, so I am using flutter_background_service to pass data to the main isolate and update app state.
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeBackgroundService();
FirebaseMessaging.onBackgroundMessage(_backgroundMessageHandler);
_initLocalNotifications();
runApp(MyApp());
}
I'm initializing the background service similarly to the example in flutter_background_service:
Future<void> initializeBackgroundService() async {
final service = FlutterBackgroundService();
await service.configure(
androidConfiguration: AndroidConfiguration(
onStart: onStart,
autoStart: true,
isForegroundMode: true,
),
iosConfiguration: IosConfiguration(
autoStart: true,
onForeground: onStart,
onBackground: onIosBackground,
),
);
await service.startService();
}
and invoking update in the _backgroundMessageHandler when a notification is received:
Future<void> _backgroundMessageHandler(
RemoteMessage message,
) async {
final service = FlutterBackgroundService();
...
service.invoke('update', {
'key1': 'val1',
'key2': 'val2',
});
}
And in the StatefulWidget for my app in the main isolate, I'm listening on the update call to receive the data:
void listenForNotificationData() {
final backgroundService = FlutterBackgroundService();
backgroundService.on('update').listen((event) async {
print('received data message in feed: $event');
}, onError: (e, s) {
print('error listening for updates: $e, $s');
}, onDone: () {
print('background listen closed');
});
}
It's never invoking the listen callback on the 'update' event. I can confirm it's calling the invoke('update') portion and calling on('update').listen, but never receiving the update. It also doesn't seem to be erroring out. Am I missing a step somewhere here?
I was encountering the same issue on flutter background service. I solved it by removing the async keyword from the callback and creating a separate async function to perform the callback operations.
void listenForNotificationData() {
final backgroundService = FlutterBackgroundService();
backgroundService.on('update').listen((event) {
print('received data message in feed: $event');
}, onError: (e, s) {
print('error listening for updates: $e, $s');
}, onDone: () {
print('background listen closed');
});
}
void action(Map? event) async {
print('received data message in feed: $event');
}
Hope it helps, forgive me if there are syntax error
You can try this.
main(){
....
}
Future<void> readyForShared() async {
var sharedPreferences = await SharedPreferences.getInstance();
counterValue = sharedPreferences.getString("yourVariable") ?? "0";
}
Future<void> saveData(String value) async {
var sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setString("yourVariable", value);
}
#pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
// Only available for flutter 3.0.0 and later
DartPluginRegistrant.ensureInitialized();
// For flutter prior to version 3.0.0
// We have to register the plugin manually
SharedPreferences preferences = await SharedPreferences.getInstance();
await preferences.setString("hello", "world");
/// OPTIONAL when use custom notification
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
if (service is AndroidServiceInstance) {
service.on('setAsForeground').listen((event) {
service.setAsForegroundService();
});
service.on('setAsBackground').listen((event) {
service.setAsBackgroundService();
});
}
service.on('stopService').listen((event) {
service.stopSelf();
});
// bring to foreground
Timer.periodic(const Duration(seconds: 1), (timer) async {
final receivePort = ReceivePort();
// here we are passing method name and sendPort instance from ReceivePort as listener
await Isolate.spawn(computationallyExpensiveTask, receivePort.sendPort);
if (service is AndroidServiceInstance) {
if (await service.isForegroundService()) {
//It will listen for isolate function to finish
// receivePort.listen((sum) {
// flutterLocalNotificationsPlugin.show(
// 888,
// 'Title',
// 'Description ${DateTime.now()}',
// const NotificationDetails(
// android: AndroidNotificationDetails(
// 'my_foreground',
// 'MY FOREGROUND SERVICE',
// icon: 'ic_bg_service_small',
// ongoing: true,
// ),
// ),
// );
// });
var sharedPreferences = await SharedPreferences.getInstance();
await sharedPreferences.reload(); // Its important
service.setForegroundNotificationInfo(
title: "My App Service",
content: "Updated at ${sharedPreferences.getString("yourVariable") ?? 'no data'}",
);
}
}
/// you can see this log in logcat
if (kDebugMode) {
// print('FLUTTER BACKGROUND SERVICE: ${deee.toString()}');
}
// test using external plugin
final deviceInfo = DeviceInfoPlugin();
String? device;
if (Platform.isAndroid) {
final androidInfo = await deviceInfo.androidInfo;
device = androidInfo.model;
}
if (Platform.isIOS) {
final iosInfo = await deviceInfo.iosInfo;
device = iosInfo.model;
}
service.invoke(
'update',
{
"current_date": '400',
"device": device,
},
);
});
}
....
....
....
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
readyForShared(); // init shared preferences
});
}
...
...
...
ElevatedButton(onPressed:(){saveData('Your Updated data.');}....