Is GetX broken ? controller not found when the app goes to background

  • Everything working well when the app is either in Foreground or Terminated

  • Flutter: 3.13.9 | GetX: 4.6.6 | get_storage: 2.1.1

    My LocalNotificationsController class extends GetxService which as mentioned in the package that the controller will be available during all app life cycle but the issue that i’m facing is that when the app goes to background the it’s no longer available.
    In my main file i’m calling initialServies

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  await initialServies();

initialServies:

class MyServices extends GetxService {
  late GetStorage localStorage;
  late FirebaseMessaging firebaseMessaging;

  Future<MyServices> init() async {
    await GetStorage.init();
    localStorage = GetStorage();
    firebaseMessaging = FirebaseMessaging.instance;

    return this;
  }
}

initialServies() async {
  await Get.putAsync(() => MyServices().init());
  await Get.putAsync(() => NotificationsService().initNotifications());
  Get.put(UsersController());
  Get.put(LocalWishlistController());
  Get.put(LocalNotificationsController());
}

LocalNotificationsController:

class LocalNotificationsController extends GetxService with WidgetsBindingObserver {
  MyServices myServices = Get.find();
  var notifications = <NotificationModel>[].obs;

  @override
  void onInit() {
    WidgetsBinding.instance.addObserver(this);
    fetchNotifications();
    super.onInit();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // fetchNotifications();
    }
  }

  @override
  void onClose() {
    WidgetsBinding.instance.removeObserver(this);
    super.onClose();
  }

  // fetch notifications from local storage
  void fetchNotifications() {
    List storedNotificationsList = myServices.localStorage.read('notifications') ?? [];
    notifications.value = storedNotificationsList.map((notification) => NotificationModel.fromJson(notification)).toList();
    notifications.sort((a, b) => b.createdAt.compareTo(a.createdAt));
  }

  // Add a new notification for the current user
  void addNotification(RemoteMessage message) {
    // Check if the notification already exists
    if (notifications.any((notification) => notification.id == message.messageId)) {
      return;
    }
    // Add the notification to the list
    notifications.insert(
      0,
      NotificationModel(
        id: message.messageId!,
        title: message.notification!.title!,
        body: message.notification!.body!,
        createdAt: Timestamp.now(),
        seen: false,
        type: message.data['type'] ?? '',
        typeId: message.data['id'] ?? '',
      ),
    );

    // Save the notification to local storage
    List<Map<String, dynamic>> notificationsMap = notifications.map((notification) => notification.toJson()).toList();
    myServices.localStorage.write('notifications', notificationsMap);
    // fetchNotifications();
  }

notifications_service.dart:

Future<void> handleBackgroundMessage(RemoteMessage message) async {
  await Firebase.initializeApp();
  await Get.putAsync(() => MyServices().init());
  final localNotificationsController = Get.put(LocalNotificationsController());
  localNotificationsController.addNotification(message);
}

Future<void> handleForegroundMessage(RemoteMessage message) async {
  if (message.notification != null) {
    Get.find<LocalNotificationsController>().addNotification(message);
    await NotificationsService()._showNotification(message);
  }
}

class NotificationsService extends GetxService {

The whole story is when receiving a notification while the app is in the background, as you see i’m obliged to use Get.put again since if i don’t do that i got the controller is not found.
So what happens is that it’s like two separated controller are created i noticed that by printing the notification list everywhere, so the notification gets successfully added but i don’t find the old notifications it’s like a new empty list and when i resume the app the list has the old notifications without the new one (same thing about the content of local storage).
And all this happen after noticing that the UI is not getting updated when received a new notification in the background (i’m using GetX builder to listen for changes in the notifications list since it’s observable in the notifications screen)

  • I already tried to use Get.put in the main file
  • I already tried to use notifications.refresh() and everywhere possible
  • I already tried to use update() everywhere possible even that the notifications is RxList which means i don’t need to use update()
  • I already tried to use refresh indicator and fetchNotifications
  • I already tried to use lazyPut, putAsync
  • I already tried to use initialBindings

  • 1

    This seven minute video presents a good detailed description of “why not getx”: youtu.be/zlIgy4es5Ts

    – 

  • have you track where/when exacly the service/controller is deleted?

    – 




Leave a Comment