Reputation: 764
I have an app that is connected to Firebase, and I am making a screen that will show all notifications sent, for that I am using SharedPreferences. But as the notification arrives on a map, I am placing it inside a List <Map <dynamic, dynamic >>, to show the notification.
String title, body;
Map<dynamic, dynamic> notific;
List<Map<dynamic, dynamic>> notifList = [];
///Widget
return Scaffold(
extendBody: true,
backgroundColor: widget._colors.white,
appBar: appBar,
body: ListView.builder(
itemCount: notifList.length,
itemBuilder: (context, i) {
return Card(
margin: EdgeInsets.all(10),
elevation: 4,
child: ListTile(
title: Text(
notifList.elementAt(i)['title'],
),
subtitle: Text(
notifList.elementAt(i)['body'],
),
),
);
},
),
);
}
Firebase Method
Future<dynamic> fcmMessageReceiver() async {
FirebaseMessaging.instance.getInitialMessage().then((value) {
if (value != null) {}
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {
notific = {
'title': message.notification.title,
'body': message.notification.body
};
notifList.add(notific);
setState(() {
title = message.notification.title;
body = message.notification.body;
});
print('MENSAGEM: $notific');
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {});
}
Shared Preferences method, being called on initState()
void savePush() async {
SharedPreferences sharePref = await SharedPreferences.getInstance();
final strList = sharePref.getStringList('push')??[];
sharePref.setStringList('push', notifList.toString());
}
My question is, how can I keep these notifications, so whenever I want to see them, I can get them easily, and set up the Cards with the notifications?
Upvotes: 0
Views: 550
Reputation: 1117
So, there are many approaches to solve this issue, some of my approaches will be to convert each message to a JSON encoded string
and then push it to the sharedPreference.setStringList(list)
. Another way is to make the whole list a JSON encoded string
and save it to SharedPreferences
like a string by calling sharedPreference.setString(list)
.
Let's say your List of the message is like this:
List<Map<String, dynamic>> messagesForUI = [];
And, you've initialized SharedPreferences
and previous messages from SharedPreferences
like this:
SharedPreferences sharedPreference = await SharedPreferences.getInstance();
List<String> sharedPreferenceMessages = [];
Now, to retrieve all your previous messages from SharedPreferences
and then set the previous messages to messagesForUI
inside the initState
method, you can do this:
sharedPreferenceMessages = sharedPreference.getStringList("messages") ?? [];
sharedPreferenceMessages.forEach((element) {
Map<String, dynamic> messageMap = Map<String, dynamic>.from(json.decode(element));
messagesForUI.add(messageMap);
});
Now, you've your list ready to roll.
Let's say you have a new message from FCM and you want to save it to the SharedPreferences
. Let's save the new message this way:
Map<String, dynamic> newMessage = Map<String, dynamic>.from(fcmMessage);
setState((){
messagesForUI.add(newMessage);
});
String newMessageJson = json.encode(newMessage);
sharedPreferenceMessages.add(newMessageJson);
sharedPreference.setStringList("messages", sharedPreferenceMessages);
There you go. You can also save messages to SharedPreferences
via calling sharedPreference.setString(map)
, just like this approach. If need a demonstration of that process, just comment here.
Sample code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class NotificationRoute extends StatefulWidget {
@override
_NotificationRouteState createState() => _NotificationRouteState();
}
class _NotificationRouteState extends State<NotificationRoute> {
List<Map<String, dynamic>> messagesForUI = [];
List<String> sharedPreferenceMessages = [];
SharedPreferences sharedPreference;
@override
void initState() {
init();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: messagesForUI.isEmpty
? Center(
child: Text("No notifications"),
)
: ListView.builder(
itemBuilder: (context, index) {
final Map<String, dynamic> message = messagesForUI[index];
return ListTile(
title: Text(message["title"]),
subtitle: Text(message["body"]),
);
},
shrinkWrap: true,
physics: ScrollPhysics(),
scrollDirection: Axis.vertical,
itemCount: messagesForUI.length,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Map<String, dynamic> newMessage = {"title": "test title", "body": "test body"};
setState(() {
messagesForUI.add(newMessage);
});
String newMessageJson = json.encode(newMessage);
sharedPreferenceMessages.add(newMessageJson);
sharedPreference.setStringList("messages", sharedPreferenceMessages);
},
child: Icon(Icons.add),
),
);
}
init() async {
sharedPreference = await SharedPreferences.getInstance();
sharedPreferenceMessages = sharedPreference.getStringList("messages") ?? [];
sharedPreferenceMessages.forEach((element) {
Map<String, dynamic> messageMap = Map<String, dynamic>.from(json.decode(element));
messagesForUI.add(messageMap);
});
}
}
Now, as I don't have any FCM
set-up on my project, I just replicate the message add process to the SharedPreference
via FloatingActionButton
.
Happy coding :D
Upvotes: 2