OneSignal / OneSignal-Flutter-SDK

OneSignal is a free push notification service for mobile apps. This plugin makes it easy to integrate your flutter app with OneSignal
https://www.onesignal.com
Other
623 stars 213 forks source link

[Bug]: OneSignal.Notifications.addForegroundWillDisplayListener does not work. (IOS) #944

Open vdiaza opened 2 months ago

vdiaza commented 2 months ago

What happened?

I have tried multiple versions, but I cannot make addForegroundWillDisplayListener nor addClickListener to handle any notification.

My notifications are not shown while the app is in the foreground. If it's in the background they work, IOS links get opened in safari But the handlers do not emit any log either.

In Android works fine

Steps to reproduce?

Here are my codes for my onesignal helper (Connected to inappwebview).

import 'dart:async';
import 'dart:developer';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:test/Utils/AppGlobal.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:test/Utils/Constants.dart';

class OneSignalNotificationHelper {
  InAppWebViewController? _webviewController;

  Future<void> initialize(InAppWebViewController webviewController) async {
    _webviewController = webviewController;

    if (Constants.oneSignalId == null || Constants.oneSignalId!.isEmpty) {
      AppGlobal.printLog('OneSignal App ID is null or empty');
      return;
    }

    // Initialize OneSignal with logging
    try {
      OneSignal.Debug.setLogLevel(OSLogLevel.verbose);
      OneSignal.initialize(Constants.oneSignalId!);
      log("OneSignal Initialized");
    } catch (e) {
      log('Error initializing OneSignal: $e');
      return;
    }

    // Check and request notification permission
    await _checkAndRequestNotificationPermission();

    // Opt-in to push notifications
    await _optInToPushNotifications();

    // Set up notification listeners
    _addNotificationListeners();
  }

  Future<void> _checkAndRequestNotificationPermission() async {
    PermissionStatus notificationPermissionStatus =
        await Permission.notification.status;
    log('Initial Notification Permission Status: $notificationPermissionStatus');

    if (notificationPermissionStatus.isDenied) {
      log('Requesting Notification Permission...');
      await OneSignal.Notifications.requestPermission(true);

      // Check permission status again after requesting
      notificationPermissionStatus = await Permission.notification.status;
      if (notificationPermissionStatus.isGranted) {
        log('Notification Permission Granted');
      } else {
        log('Notification Permission Denied or Not Determined');
      }
    }
  }

  Future<void> _optInToPushNotifications() async {
    try {
      await OneSignal.User.pushSubscription.optIn();
      log('Successfully opted in to push notifications.');
    } catch (e) {
      log('Error opting in to push notifications: $e');
    }
  }

  void _addNotificationListeners() {
    OneSignal.Notifications.addClickListener((event) {
      log('Notification Clicked: ${event.notification.jsonRepresentation()}');
      _handleNotificationRedirection(event.notification);
    });

    OneSignal.Notifications.addForegroundWillDisplayListener((event) {
      log('Foreground Notification Received: ${event.notification.jsonRepresentation()}');

      // event.preventDefault();
      event.notification.display();
    });
  }

  Future<void> _handleNotificationRedirection(
      OSNotification notification) async {
    String? url = notification.rawPayload?['url'] as String?;
    if (url != null && _webviewController != null) {
      try {
        await _webviewController?.loadUrl(
            urlRequest: URLRequest(url: WebUri(url)));
        log('URL loaded in webview: $url');
      } catch (e) {
        log('Failed to load URL in webview: $e');
      }
    } else {
      log('No URL found in notification payload or webview controller is null.');
    }
  }
}

AppDelegate.swift

import Flutter
import UIKit
import flutter_background_service_ios
import FirebaseCore
import app_links

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    SwiftFlutterBackgroundServicePlugin.taskIdentifier = "id.flutter.flutter_background_service.BackgroundService"

    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }

    GeneratedPluginRegistrant.register(with: self)

    // Retrieve the link from parameters
    if let url = AppLinks.shared.getLink(launchOptions: launchOptions) {
      // We have a link, propagate it to your Flutter app or not
      AppLinks.shared.handleLink(url: url)
      return true // Returning true will stop the propagation to other packages
    }

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  override func application(
    _ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
  ) -> Bool {
    if let incomingURL = userActivity.webpageURL {
      // Handle the Universal Link in Flutter
      AppLinks.shared.handleLink(url: incomingURL)
      return true  // Indicate that the URL has been handled
    }
    return false
  }
}

### What did you expect to happen?

To show logs and open the notification while the app is in the foreground

### OneSignal Flutter SDK version

5.2.3

### Which platform(s) are affected?

- [X] iOS
- [ ] Android

### Relevant log output

```Shell
flutter doctor -v
[✓] Flutter (Channel stable, 3.24.1, on macOS 14.4.1 23E224 darwin-arm64, locale
    en-CL)
    • Flutter version 3.24.1 on channel stable at
      /Users/vicentediaz/workspace/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 5874a72aa4 (8 days ago), 2024-08-20 16:46:00 -0500
    • Engine revision c9b9d5780d
    • Dart version 3.5.1
    • DevTools version 2.37.2

[✓] Android toolchain - develop for Android devices (Android SDK version
    34.0.0-rc1)
    • Android SDK at /Users/vicentediaz/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0-rc1
    • ANDROID_HOME = /Users/vicentediaz/Library/Android/sdk
    • ANDROID_SDK_ROOT = /Users/vicentediaz/Library/Android/sdk
    • Java binary at:
      /usr/local/Cellar/openjdk@17/17.0.12/libexec/openjdk.jdk/Contents/Home/bin/j
      ava
    • Java version OpenJDK Runtime Environment Homebrew (build 17.0.12+0)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15F31d
    • CocoaPods version 1.15.2

[✗] Chrome - develop for the web (Cannot find Chrome executable at
    /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Android Studio (version 2022.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • android-studio-dir = /Applications/Android Studio.app
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)

[✓] VS Code (version 1.92.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.94.0

[✓] Connected device (4 available)
    • iPhone 15 Pro (mobile)          • 17908AB5-0F66-4925-899D-FCB97294FC4F • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-17-4 (simulator)
    • macOS (desktop)                 • macos                                •
      darwin-arm64 • macOS 14.4.1 23E224 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad                •
      darwin       • macOS 14.4.1 23E224 darwin-arm64
    ! Error: Browsing on the local area network for iPhone de Cristian. Ensure the
      device is unlocked and attached with a cable or associated with the same
      local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code
      -27)

[✓] Network resources
    • All expected network resources are available.

Code of Conduct