Kaya Ryuuna
Kaya Ryuuna

Reputation: 764

Flutter - SharedPreferences saving list

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

Answers (1)

Omar Khaium Chowdhury
Omar Khaium Chowdhury

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

Related Questions