0

I'm running a method inside the initState() of my Flutter app that perform oneSignal initialization

part of this method is sending tags of the user to the OneSignal Api but according to their documentations

they said that this method of sending tags take arround 5 seconds so the recommendation is not to block other tasks

so I decided to run it inside a new spawned isolate but I got this error message

Unhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
E/flutter ( 2679): If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
E/flutter ( 2679): If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.

and I still getting the same error message even after running the following method inside my main method just before the runApp(myApp())

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  setup();
  bool isAcademic = HelperFucntions.isAcademic(await UserCachedInfo().getRecord('account_type'));
  runApp(MyApp(isAcademic));
}

this is the method that I want to run it inside a new isolate

_handleOneSignalRegistration(String d)async{
  String userId;
  while (userId == null) {
    var data = await OneSignal.shared.getPermissionSubscriptionState();
    userId = data.subscriptionStatus.userId;
    if (userId != null) {
      print('*******************************************************************');
      print('we got it inside while loop => $userId');
      await CachingServices.saveStringField(key: 'one_signal_id', value: userId);
      print('************************************************************************');

      print('===================================== fetching tags');
      final Map<String,dynamic> myTags = await OneSignal.shared.getTags();
      print(myTags);
//          final Map<String,dynamic> tags = await HelperFucntions.getUserTags();
//          if(tags != null){
//            OneSignal.shared.sendTags(tags);
//          }
    }
  }
}

and this is the method of initialization that I call inside the initState method

  Future<void> initialize() async {
    if (_isInitialized) {
      return;
    }
    LocalNotificationService localNotificationService = LocalNotificationService.getInstance();
    await localNotificationService.initialize();

    OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);

    OneSignal.shared.init(
      ONE_SIGNAL_ID,
      iOSSettings: {OSiOSSettings.autoPrompt: false, OSiOSSettings.inAppLaunchUrl: false},
    );
    OneSignal.shared.setInFocusDisplayType(OSNotificationDisplayType.none);



// The promptForPushNotificationsWithUserResponse function will show the iOS push notification prompt. We recommend removing the following code and instead using an In-App Message to prompt for notification permission
    await OneSignal.shared.promptUserForPushNotificationPermission(fallbackToSettings: true);

    WidgetsFlutterBinding.ensureInitialized();
    // this will spawn an Isolate so in order not to block the main isolate
    compute(_handleOneSignalRegistration,'d');
    OneSignal.shared.setNotificationReceivedHandler(
      (OSNotification notification) {
        print(++_channelID);
        NotificationStateProvider notificationStateProvider = locator.get<NotificationStateProvider>();
        var receivedNotification;
        try {
          receivedNotification = new NotificationInstance(
            title: notification.payload.title,
            body: notification.payload.body,
            id: notification.payload.notificationId,
            sentAt: DateTime.fromMillisecondsSinceEpoch(notification.payload.rawPayload['google.sent_time']),
          );
          notificationStateProvider.addToNotificationsList(receivedNotification);
        } catch (err) {
          throw err;
        }

      },
    );
    _isInitialized = true;
  }
Karrar
  • 1,273
  • 3
  • 14
  • 30
  • Concurrency is not needed here. You can run your code async then update the screen when complete. – easeccy Jul 30 '20 at 13:47
  • 1
    I do run the method in async and it works fine but suppose this method needed to be run in new isolate , what is the problem of not working ?? – Karrar Jul 30 '20 at 13:55

0 Answers0