How to save push notifications from fcm firebase to hive db, in the background with flutter

480

After some research, I found that hive does not support multithreading, but I implemented a different way, I save the notifications in a json file, this does not affect the isolation. The notifications are saved when the phone is locked, or the application is closed and when the application is opened the notifications are visible.

Here is a general implementation, it may be of your help

https://cutt.ly/qW3frDi

Share:
480
IsaDev
Author by

IsaDev

Updated on December 30, 2022

Comments

  • IsaDev
    IsaDev over 1 year

    I have been making a flutter application and I have a notifications section, and I have been trying to save the push notifications in the Hive database in the background or when the cell phone is blocked, I don't want to use StopWatch or similar packages to this, as I think it is annoying for the user, the error I get is this:

    /FLTFireMsgReceiver(31121): broadcast received for message
    W/FirebaseMessaging(31121): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
    I/flutter (31121): 
    E/flutter (31121): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: HiveError: You need to initialize Hive or provide a path to store the box.
    E/flutter (31121): #0      BackendManager.open (package:hive/src/backend/vm/backend_manager.dart:16:7)
    E/flutter (31121): #1      HiveImpl._openBox (package:hive/src/hive_impl.dart:106:30)
    E/flutter (31121): #2      HiveImpl.openBox (package:hive/src/hive_impl.dart:145:18)
    E/flutter (31121): #3      DbProviderHive.openBoxNotification (package:myproyectapp/src/services/database/hive/db_provider_hive.dart:80:42)
    E/flutter (31121): <asynchronous suspension>
    E/flutter (31121): #4      NotificationDao._getDbInstance (package:myproyectapp/src/services/database/daos/nofication_dao.dart:14:11)
    E/flutter (31121): <asynchronous suspension>
    E/flutter (31121): #5      NotificationDao.insert.<anonymous closure> (package:myproyectapp/src/services/database/daos/nofication_dao.dart:20:9)
    E/flutter (31121): <asynchronous suspension>
    E/flutter (31121): #6      _QueuedFuture.execute (package:queue/src/dart_queue_base.dart:26:16)
    E/flutter (31121): <asynchronous suspension>
    E/flutter (31121): 
    I/flutter (31121): ----------------FIREBASE CRASHLYTICS----------------
    I/flutter (31121): The following exception was thrown Internal Record Error:
    I/flutter (31121): MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
    I/flutter (31121): 
    I/flutter (31121): ----------------------------------------------------
    

    And this is my code where I get the DB instance, when the app is in foreground it works correctly for me.

    class DbProviderHive {
      static final DbProviderHive _singleton = DbProviderHive._internal();
    
      static Box<NotificationModel> _boxNotificationModel;
    
      factory DbProviderHive() {
        return _singleton;
      }
    
      DbProviderHive._internal();
    
      static Future<void> _initSettings() async {
        // Se encarga de guardar la BD en un directorio valido
        final folderName = 'myDB';
    
        final databasePath = await getDatabasesPath();
        if (await Directory(join(databasePath, folderName)).exists()) {
          await Directory(join(databasePath, folderName)).delete(recursive: true);
        }
    
        await Hive.initFlutter(join(databasePath, folderName));
      }
    
    static Future<void> _initHiveDatabase() async {
        try {
          await _initSettings();
          Hive.registerAdapter(NotificationModelAdapter()); // TypeId: 0
          print("");
        } catch (e) {
          debugPrint("");
        }
    
      static Future<Box<NotificationModel>> openBoxNotification() async {
        if (_boxNotificationModel == null) {
          await _initHiveDatabase();
          _boxNotificationModel = await Hive.openBox<NotificationModel>(NotificationModel.tableName);
        }
    
        if (!_boxNotificationModel.isOpen) {
          _boxNotificationModel = await Hive.openBox<NotificationModel>(NotificationModel.tableName);
        }
        return _boxNotificationModel;
      }
    
      static Future<void> dispose() async {
        await Hive.close();
      }
    }
    

    Do you have any idea how to save the notifications in the background?

    • Alexa289
      Alexa289 over 2 years
      do you find the solution?
    • IsaDev
      IsaDev over 2 years
      No, for the moment it is the same way, I'm still looking, but what I plan to do using sqlite, with this DB I have no problem, in this scenario
  • cigien
    cigien over 2 years
    Please add sufficient code into the answer itself, so that it's still useful even if the link dies.